阿萨德按时 发表于 2022-1-4 09:55:42

相同程序在windows的devc++和ubuntu下求出的结果为什么不一样

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

int main()
{
    double result = 0;

    for(int i=0; i<64; i++){
      result += pow(2, i);
    }

    printf("result = %.0f\n", result);

    return 0;
}

人造人 发表于 2022-1-4 11:09:05

这两个输出都不对
第一个是因为double类型本身的精度误差造成的,这可以理解
要么接受这个误差,要么换用第三方库
你的第二个输出确实奇怪,不知道你是怎么弄出来的

$ cat main.py
#!/usr/bin/env python
#coding=utf-8

result = 0
for i in range(64):
    result += pow(2, i)
print(result)
$ ./main.py
18446744073709551615
$
$
$ cat main.c
#include <stdio.h>
#include <math.h>

int main()
{
    double result = 0;

    for(int i=0; i<64; i++){
      result += pow(2, i);
    }

    printf("result = %.0f\n", result);

    return 0;
}
$ ./main
result = 18446744073709551616
$

阿萨德按时 发表于 2022-1-4 11:20:39

人造人 发表于 2022-1-4 11:09
这两个输出都不对
第一个是因为double类型本身的精度误差造成的,这可以理解
要么接受这个误差,要么换用 ...

就直接编译运行就是这个结果,我也很奇怪

人造人 发表于 2022-1-4 11:38:39

阿萨德按时 发表于 2022-1-4 11:20
就直接编译运行就是这个结果,我也很奇怪

那就贴一下反汇编代码,我来研究研究

阿萨德按时 发表于 2022-1-4 13:53:00

人造人 发表于 2022-1-4 11:38
那就贴一下反汇编代码,我来研究研究

{:10_282:} 我是萌新 是这样搞吗

人造人 发表于 2022-1-4 15:36:14

试一试下面这些代码
#include <stdio.h>
#include <math.h>

int main()
{
    float result = 0;

    for(int i=0; i<64; i++){
      result += pow(2, i);
    }

    printf("result = %.0f\n", result);

    return 0;
}


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

int main()
{
    double result = 0;

    for(int i=0; i<64; i++){
      result += pow(2, i);
    }

    printf("result = %.0lf\n", result);

    return 0;
}


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

int main()
{
    printf("%lu\n", sizeof(float));
    printf("%lu\n", sizeof(double));
    return 0;
}

阿萨德按时 发表于 2022-1-4 15:48:47

人造人 发表于 2022-1-4 15:36
试一试下面这些代码

上面两段还是一样result = 18446744073709552000
最后一段是4和8

人造人 发表于 2022-1-4 20:07:16

阿萨德按时 发表于 2022-1-4 15:48
上面两段还是一样result = 18446744073709552000
最后一段是4和8

看看这个输出什么

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

int main()
{
    double result = 0;

    for(int i=0; i<64; i++){
      result += pow(2, i);
    }

    //printf("result = %.0f\n", result);
    const unsigned char *base = (const unsigned char *)&result;
    for(size_t i = 0; i < 8; ++i) {
      printf("%.2x ", base);
    }
    puts("");

    return 0;
}

阿萨德按时 发表于 2022-1-5 08:27:03

人造人 发表于 2022-1-4 20:07
看看这个输出什么

00 00 00 00 00 00 f0 43

人造人 发表于 2022-1-5 12:32:14

阿萨德按时 发表于 2022-1-5 08:27
00 00 00 00 00 00 f0 43

我这边也输出这个,说明上面的for循环计算出的result是正确的,问题出在printf
看看这个输出什么
#include <stdio.h>
#include <math.h>

int main()
{
    double result = 0;

    for(int i=0; i<64; i++){
      result += pow(2, i);
    }

    //printf("result = %.0f\n", result);
    const unsigned char *base = (const unsigned char *)&result;
    for(size_t i = 0; i < 8; ++i) {
      printf("%.2x ", base);
    }
    puts("");
    printf("result = %f\n", result);
    printf("result = %lf\n", result);
    printf("result = %.23e\n", result);
    printf("result = %.23le\n", result);
    printf("result = %.23E\n", result);
    printf("result = %.23lE\n", result);

    return 0;
}


我这边输出这个
00 00 00 00 00 00 f0 43
result = 18446744073709551616.000000
result = 18446744073709551616.000000
result = 1.84467440737095516160000e+19
result = 1.84467440737095516160000e+19
result = 1.84467440737095516160000E+19
result = 1.84467440737095516160000E+19

人造人 发表于 2022-1-5 12:36:30

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

int main()
{
    double result = 18446744073709551616.0;
    const unsigned char *base = (const unsigned char *)&result;
    for(size_t i = 0; i < 8; ++i) {
      printf("%.2x ", base);
    }
    puts("");
    printf("result = %lf\n", result);
    return 0;
}


00 00 00 00 00 00 f0 43
result = 18446744073709551616.000000

阿萨德按时 发表于 2022-1-5 13:10:34

人造人 发表于 2022-1-5 12:32
我这边也输出这个,说明上面的for循环计算出的result是正确的,问题出在printf
看看这个输出什么



00 00 00 00 00 00 f0 43
result = 18446744073709552000.000000
result = 18446744073709552000.000000
result = 1.84467440737095520000000e+019
result = 1.84467440737095520000000e+019
result = 1.84467440737095520000000E+019
result = 1.84467440737095520000000E+019

阿萨德按时 发表于 2022-1-5 13:11:40

人造人 发表于 2022-1-5 12:36


00 00 00 00 00 00 f0 43
result = 18446744073709552000.000000

人造人 发表于 2022-1-5 13:42:31

阿萨德按时 发表于 2022-1-5 13:11
00 00 00 00 00 00 f0 43
result = 18446744073709552000.000000

问题出在printf,如果仔细看输出结果的话
前面全一样,只有后4位不一样
一个是 1616,一个是 2000
在第一个 6 的位置四舍五入就是 2000
这其实是printf的精度问题,误差有点大对吧
但是这误差其实不大,这么大的数字就差了 384
>>> 18446744073709552000-18446744073709551616
384
>>> 384/18446744073709551616
2.0816681711721685e-17
>>> "{:.30f}".format(384/18446744073709551616)
'0.000000000000000020816681711722'
>>>

你使用的编译系统可能有点老了,升级一下你的编译系统吧

阿萨德按时 发表于 2022-1-5 13:52:21

人造人 发表于 2022-1-5 13:42
问题出在printf,如果仔细看输出结果的话
前面全一样,只有后4位不一样
一个是 1616,一个是 2000


好的谢谢大佬
页: [1]
查看完整版本: 相同程序在windows的devc++和ubuntu下求出的结果为什么不一样