gpt4 book ai didi

从 double 到 int 的转换可以用可移植的 C 编写吗

转载 作者:太空狗 更新时间:2023-10-29 16:29:57 26 4
gpt4 key购买 nike

我需要编写类似 double_to_int(double val, int *err) 的函数哪一个在可能的情况下将 double val 转换为整数;否则报错(NAN/INFs/OUT_OF_RANGE)。

所以伪代码实现看起来像:

if isnan(val):
err = ERR_NAN
return 0
if val < MAX_INT:
err = ERR_MINUS_INF
return MIN_INT
if ...
return (int)val

SO上至少有两个类似的问题:在this回答它以足够干净的方式解决,尽管它是 C++ 解决方案——在 C 中,我们没有用于签名 int 的可移植数字。在 this答案,它解释了为什么我们不能只检查 (val > INT_MAX || val < INT_MIN) .

所以我看到的唯一可能的干净方法是使用浮点环境,但它被声明为实现定义的功能。

所以我的问题是:有什么方法可以实现 double_to_int跨平台功能(仅基于C标准,甚至不考虑支持 IEEE-754 的目标平台)。?

最佳答案

可以用可移植的 C 编写从 double 到 int 的对话”的答案显然是“是的”。

例如,您可以将浮点值 sprintf 转换为字符串,进行基于字符串的检查(即通过基于字符串的与最大值和最小值的比较,您也可以 sprintf'd)、验证、舍入等,然后扫描已知的值- 最终值的有效字符串。

实际上,您将转向 (a) 可移植且 (b) 方便的中间表示。 C 字符串的可移植性很好,但不太方便。如果可以使用外部库,有几个比较方便,但需要确认其可移植性。

例如(省略舍入):

#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <string.h>

int convert(double inVal) {
// basic range check - does anybody have an integer format with more than 300 bits?
if (fabs(inVal) > 1.0E100) {
printf("well out of range");
return 1;
}

// load string buffer with input
char buf[110];
sprintf(buf, "%0105.0f", inVal);

// do range check on strings
if (inVal < 0) {
char minVal[110];
sprintf(minVal, "%0105d", INT_MIN);
if (strcmp(buf, minVal) > 0) {
printf("too small input: %f\n", inVal);
return -1; // needs better error signify
}
} else {
char maxVal[110];
sprintf(maxVal, "%0105d", INT_MAX);
if (strcmp(maxVal, buf) < 0) {
printf("too large input: %f\n", inVal);
return -1; // needs better error signify
}
}

// do final conversion
int result;
sscanf(buf, "%d", &result);

printf("input: %f result: %d\n", inVal, result); // diagnostic

return result;
}

int main()
{
// test values
convert( 0.);
convert( -123.5);
convert( 123.5);

convert( ((double)INT_MIN)-1);
convert( ((double)INT_MIN));
convert( ((double)INT_MIN)+1);
convert( 2.0*((double)INT_MIN));
convert( ((double)INT_MIN)/2);

convert( ((double)INT_MAX)-1);
convert( ((double)INT_MAX));
convert( ((double)INT_MAX)+1);
convert( 2.0*((double)INT_MAX));
convert( ((double)INT_MAX)/2);

return 0;
}

产生预期的转化(见上文末尾的测试用例):

% gcc test.c ; ./a.out
input: 0.000000 result: 0
input: -123.500000 result: -124
input: 123.500000 result: 124
too small input: -2147483649.000000
input: -2147483648.000000 result: -2147483648
input: -2147483647.000000 result: -2147483647
too small input: -4294967296.000000
input: -1073741824.000000 result: -1073741824
input: 2147483646.000000 result: 2147483646
input: 2147483647.000000 result: 2147483647
too large input: 2147483648.000000
too large input: 4294967294.000000
input: 1073741823.500000 result: 1073741824

关于从 double 到 int 的转换可以用可移植的 C 编写吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51104995/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com