可不可以讲一下为什么输出不一样啊

img


为什么输出和输入不一样了啊
是因为精度的有效数字不够了吗(我瞎猜的)
感谢各位讲解

C语言中的浮点数采用IEEE 754标准来表示实数,但是由于计算机内部的存储方式和运算方式的限制,导致浮点数无法精确存储。

具体来说,计算机中使用二进制来表示浮点数,而二进制无法准确地表示某些小数部分,例如0.1这个小数。因此,在计算机中,浮点数是以近似值的形式存储的。

此外,计算机中使用的浮点数还受到指数位的影响。指数位决定了浮点数的小数部分的精度,但是指数位只能表示有限个二进制数字(通常为8位),因此也限制了浮点数的精度。

综上所述,由于计算机内部的存储方式和运算方式的限制,C语言中的浮点数无法精确存储。
C语言中的浮点数采用IEEE 754标准来表示实数,但是由于计算机内部的存储方式和运算方式的限制,导致浮点数无法精确存储。

具体来说,计算机中使用二进制来表示浮点数,而二进制无法准确地表示某些小数部分,例如0.1这个小数。因此,在计算机中,浮点数是以近似值的形式存储的。

此外,计算机中使用的浮点数还受到指数位的影响。指数位决定了浮点数的小数部分的精度,但是指数位只能表示有限个二进制数字(通常为8位),因此也限制了浮点数的精度。

综上所述,由于计算机内部的存储方式和运算方式的限制,C语言中的浮点数无法精确存储。

可以看一下 hadao 博客的文章“实型数据解析”

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7672904
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:【指针】统计一字符串在另一个字符串中出现的次数
  • 除此之外, 这篇博客: 【程序员的自我修养】[动态图文] 超详解函数栈帧中的 函数返回 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 函数返回并没有看上去那么简单:

    return z; 语句之后,其实都是函数返回需要进行的操作。

    1. 首先是,return z;
      返回值操作是,mov eax,dword ptr [ebp-8]
      ebp-8(z) 处的两字(4字节) 的值存入 寄存器 eax
      返回 z 的操作,其实就是将 z 的值,存入了寄存器中。
      当函数使用完后,局部变量会被销毁,但是寄存器在CPU中是不会被销毁的。
      所以将 局部变量 z 的值 存放在寄存器中,就能达到返回 z 的值 的效果。
      return_z

    2. 再按顺序将:
      在进入 Add 函数后 压栈的 edi, esi, ebx 三个内容退栈
      pop_edi_esi_ebx

    3. 然后将 ebp 的值 给 esp
      esp 的值变为 ebp 的值的时候,Add 函数栈帧的维护就结束了。Add 函数栈帧的空间就会还给内存。
      mov_esp,esp

    4. 再然后就是 pop ebp
      pop ebp 与 一般 pop 其他内容不同,pop ebp 还会将这里需要弹出的 ebp 的值 给 寄存器 ebp
      pop_ebp
      此时,espebp 两个维护栈帧的寄存器,就又去维护 main 函数栈帧了。

    这整个过程的动画:

    1. 最后一步就是 ret 指令
      Add 函数使用结束之后,汇编代码应该继续回到 main 函数中的 call 指令的下一条语句的地方:
      即这里:
      return 应该回到的位置
      那么怎么才能回到这里呢?
      回想一下,在 espebp 重新维护main 函数栈帧的时候,esp 指向的地址,其实就是之前 call 指令执行时,压栈压入的 call 指令的下一条指令的地址:
      ret的地址
      ret 指令执行之后,会直接把这个空间弹出栈,然后返回到这个空间存放的地址的指令处:
      ret
      返回main函数

    这些步骤执行之后,逻辑成功从 Add 函数中返回到 main 函数中。

    继续执行代码:
    add esp,8:
    esp+8

    mov dword ptr [ebp-20h],eax:

    代码走到这里,函数栈帧的大部分内容都已经讲的很清楚了。本篇文章到这里也就结束了。


  • 您还可以看一下 宋舒旻老师的一个简单而有效的量化投资策略课程中的 一个简单量化策略的构建与实现小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    该问题可能由于精度有效数字不够导致,出现了舍入误差。可以考虑使用高精度计算来避免产生舍入误差。具体实现方式可以参考以下几种语言的实现方案:

    Python:

    可以使用Python内置的decimal模块来实现高精度计算。在读入数据时,将输入的字符串转成decimal.Decimal类型,输出时再转成float类型即可。

    示例代码:

    from decimal import Decimal
    
    total = Decimal(0)
    while True:
        try:
            x = input()
            total += Decimal(x)
            if not x:
                print(float(total))
                total = Decimal(0)
        except:
            break
    

    Java:

    Java可以使用BigDecimal类实现高精度计算。在读入数据时,使用BigDecimal的构造函数将输入的字符串转成BigDecimal类型,输出时再使用BigDecimal的doubleValue()方法转成double类型即可。

    示例代码:

    import java.util.Scanner;
    import java.math.BigDecimal;
    
    public class Main {
        public static void main(String[] args) {
            BigDecimal total = BigDecimal.ZERO;
            Scanner scanner = new Scanner(System.in);
            while (true) {
                try {
                    String x = scanner.nextLine().trim();
                    total = total.add(new BigDecimal(x));
                    if (x.equals("")) {
                        System.out.println(total.doubleValue());
                        total = BigDecimal.ZERO;
                    }
                } catch (Exception e) {
                    break;
                }
            }
            scanner.close();
        }
    }
    

    C++:

    C++可以使用第三方库如GMP实现高精度计算。在读入数据时,使用GMP提供的函数将输入的字符串转成mpz_class类型,输出时再使用mpz_class的get_d()方法转成double类型即可。

    示例代码:

    #include <gmpxx.h>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main() {
        mpz_class total(0);
        string line;
        while (true) {
            try {
                getline(cin, line);
                if (line.empty()) {
                    cout << total.get_d() << endl;
                    total = mpz_class(0);
                } else {
                    total += mpz_class(line);
                }
            } catch(...) {
                break;
            }
        }
    
        return 0;
    }
    

    注意,在使用GMP时需要先安装该库。

    需要注意的是,使用高精度计算会带来一定的时间复杂度和空间复杂度,具体取决于所选用的高精度计算方法和数据规模。如需进一步优化程序,可以考虑使用一些高效的高精度计算算法,并适当控制数据规模。