Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone DBL_MAX在从字符串重新解析后会丢失其大部分精度_Iphone_C_Cocoa Touch_Inexact Arithmetic - Fatal编程技术网

Iphone DBL_MAX在从字符串重新解析后会丢失其大部分精度

Iphone DBL_MAX在从字符串重新解析后会丢失其大部分精度,iphone,c,cocoa-touch,inexact-arithmetic,Iphone,C,Cocoa Touch,Inexact Arithmetic,我在iPhone上运行以下代码: double d = DBL_MAX; NSString *s = [NSString stringWithFormat:@"%.0f", d]; double dp = atof([s cStringUsingEncoding:[NSString defaultCStringEncoding]]); NSString *pe = d == dp ? @"YES" : @"NO"; double one = 1; double dpd = dp / one;

我在iPhone上运行以下代码:

double d = DBL_MAX;
NSString *s = [NSString stringWithFormat:@"%.0f", d];
double dp = atof([s cStringUsingEncoding:[NSString defaultCStringEncoding]]);
NSString *pe = d == dp ? @"YES" : @"NO";

double one = 1;
double dpd = dp / one;
NSString *de = d == dpd ? @"YES" : @"NO";

NSLog(@"### Parsed are equal: %@, divided are equal: %@", pe, de);
NSLog(@"D   : %.0f", d);
NSLog(@"DP  : %.0f", dp);
NSLog(@"DPD : %.0f", dpd);
…并获得此输出:

### Parsed are equal: NO, divided are equal: NO
D   : 17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955863276687817154045895351438246423432132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334827479
DP  : 17976931348623155723920577891946972866121062246621938439403251722449088432276750723756897307653964877256701669823356283705419341284625019355047863102662518251134787976961389628366367996124520722972986881016593281354069269901878996004952428787693676134400
DPD : 17976931348623155723920577891946972866121062246621938439403251722449088432276750723756897307653964877256701669823356283705419341284625019355047863102662518251134787976961389628366367996124520722972986881016593281354069269901878996004952428787693676134400
为什么
printf()
/
atof()
序列会失去精度(我假设
stringWithFormat
在内部执行
printf
?它不仅适用于DBL_MAX,而且适用于每一个非常大的数字(即,对于
10000
它按预期工作,对于
DBL_MAX/2
它不工作)。有办法避免吗?

“有效”,双精度井有53位精度,即15到16位十进制数字之间,第17位有差异(但第一位数字是1)


我的猜测(我没有检查)是,差异只存在于double的较低有效位,因此在输出或输入例程中都存在舍入问题。我不知道在这种情况下,目标C是否要求正确的结果(正确的结果要求使用多精度算法),我知道C的实现是不同的。

并非所有的小数都可以用二进制表示。例如,0.2(dec)=0.001100110011…(bin)。所以,当数字从十进制字符串转换时,它有时会被截断(或四舍五入)

当从二进制转换为十进制时,即使总是可能的,结果有时也比n*log_10(2)长,其中n是二进制位数。例如,0.001(bin)=0.125(dec),但3*log_10(2)=0.903。。。所以,当数字从二进制转换为数字字符串时,它有时也会被截断

这就是为什么得到的结果略有不同的原因

这里有一个例子。假设你的尾数是6位数。让我们将数字0.001111(bin)转换为十进制。精确的结果是0.234375,但是这个数字被四舍五入到0.23,因为您只需要6*log_10(2)=1.8061位来表示任何6位二进制。在这种情况下,1.8061甚至被四舍五入为2

现在让我们看看如果我们将0.23转换回二进制,会得到什么。是0.0011101011。。。
必须对其进行四舍五入,结果可能是0.001110或0.001111,具体取决于四舍五入的方式。

如果使用
-doubleValue
而不是
atof()
?@RichardJ.RossIII:没有变化。输出正好是same@sch,在900719925474091(2^53-1)之后,整数中有空穴,可以用双精度表示。保存往返输入->输出的输入值是不可能的。但是Sergey会先输出,然后输入。可以以这样的方式实现输入和输出,即往返保存值。这显然没有完成。