x86系统数据精度问题

#将txt文件中的数据全部加10,放入新的txt文件。可是数据计算后精度出现问题?结果有一些数据不是+10,精度有问题

要求:我是在x86系统上运行的不行,可是换成x64的系统就没问题了。求解决,teacher说非要在x86系统上运行,让我解决这个精度问题。

img

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    FILE* fp_read = fopen("test1.txt", "r");
    FILE* fp_write = fopen("new.txt", "w");
    if (fp_read == NULL || fp_write == NULL)
    {
        perror("Can't open this file!");
        return -1;
    }
    char* array = new char[512]{ 0 }; //临时存放读出来的数据
    char temp = 0;                  //一个字符一个字符读
    int i = 0;                      //计数数组第几个
    while ((temp = fgetc(fp_read)) != EOF)
    {
        if (temp == '\n' || temp == ',')    //如果遇到了逗号或者换行,就说明一个有用的数据已经完整读出 
        {
            bool is_float = false;   //判断是否为浮点数
            int j;
            for (j = 0; j < i; j++)
            {
                if (array[j] == '.')
                {
                    is_float = true;    //是浮点数
                    break;
                }
            }
            if (is_float)    //如果是浮点数
            {
                double num = atof(array);
                num += 10.0;
                fprintf(fp_write, "%.*lf", i - j - 1, num);   //*是用来控制输出的小数位数
            }
            else    //如果是整数
            {
                int num = atoi(array);
                num += 10;
                fprintf(fp_write, "%d", num);
            }
            i = 0;  //计数归零
            memset(array, 0, sizeof(array));  //清空数组
            fputc(temp, fp_write);
        }
        else if (temp >= 0)    //有用字符
        {
            array[i++] = temp;
        }
    }

    fclose(fp_read);
    fclose(fp_write);       //关闭文件
    delete[]array;         //释放空间
    return 0;
}

实在不行你可以直接处理字符串,不用浮点数的加减法

x86处理器采用了IEEE 754浮点数运算标准
但在实际应用中,由于指令集的限制和硬件设计的问题
浮点数的运算存在精度损失和溢出等问题。

只有66.02出错?

给你一个可能的解决方法,将误差计算出来后,人为提高精确度

可以考虑使用 Decimal 类型(例如 Java 中的 BigDecimal),它可以提供更高的精度。这将避免浮点数表示带来的问题。在读取数据时将其转换为 Decimal 进行计算,然后再保存回 txt 文件。

【以下回答由 GPT 生成】

解决在x86系统上计算数据后精度出现问题的方法是使用更精确的数据类型来存储和计算数据。在代码中,浮点数使用的是double类型,而整数没有提及具体的数据类型。下面是一种解决方案:

  1. 将浮点数的存储和计算改为使用double类型。在代码中,使用atof函数将字符数组转换为浮点数,然后进行计算。atof函数返回一个double类型的浮点数。确保代码中num的类型为double,这样可以提高计算的精度。
double num = atof(array);
num += 10.0;
fprintf(fp_write, "%.*lf", i - j - 1, num);
  1. 将整数也改为使用更精确的数据类型,如intlong long。在代码中,如果是整数,需要将数据转换为相应的整型,然后进行计算。具体的代码要根据实际情况来决定使用哪种整型。确保代码中的整型变量的类型和范围足够大,以存储计算后的数据。

  2. 修改输出格式化的代码。在代码中,使用fprintf函数将计算后的数据写入新的txt文件中。确保输出的格式化字符串正确地控制小数位数。在代码中,使用%.*lf来控制输出的小数位数,其中*表示通过参数传递小数位数的值。

例如,修改后的代码可以是:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    FILE* fp_read = fopen("test1.txt", "r");
    FILE* fp_write = fopen("new.txt", "w");
    if (fp_read == NULL || fp_write == NULL)
    {
        perror("Can't open this file!");
        return -1;
    }
    char* array = new char[512]{ 0 }; //临时存放读出来的数据
    char temp = 0;                  //一个字符一个字符读
    int i = 0;                      //计数数组第几个
    while ((temp = fgetc(fp_read)) != EOF)
    {
        if (temp == '\n' || temp == ',')    //如果遇到了逗号或者换行,就说明一个有用的数据已经完整读出
        {
            bool is_float = false;   //判断是否为浮点数
            int j;
            for (j = 0; j < i; j++)
            {
                if (array[j] == '.')
                {
                    is_float = true;    //是浮点数
                    break;
                }
            }
            if (is_float)    //如果是浮点数
            {
                double num = atof(array);
                num += 10.0;
                fprintf(fp_write, "%.*lf", i - j - 1, num);   //*是用来控制输出的小数位数
            }
            else    //如果是整数
            {
                // 更改为适当的整型
                long long num = atoll(array);
                num += 10;
                fprintf(fp_write, "%lld", num);
            }
            // 其他代码
        }
        // 其他代码
    }
    // 其他代码

    delete[] array; // 释放动态分配的内存

    fclose(fp_read);
    fclose(fp_write);

    return 0;
}

请注意,代码中的注释是为了解释一些修改步骤和思路,实际运行时可以删除或保留。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

转换为整型加10,小数部分直接用字符串拼上即可。

转成string,然后再加减

援引讯飞星火:
这个问题可能是由于在x86系统上,double类型和int类型的大小不同导致的。在x86系统上,double类型通常为8字节,而int类型为4字节。当你将一个double类型的值加10后,可能会丢失一些精度,导致计算结果不准确。

为了解决这个问题,你可以在将double类型的值转换为int类型时进行四舍五入,然后再将其转换回double类型。这样可以避免精度丢失的问题。你可以使用round()函数进行四舍五入。

修改后的代码如下:

#include <iostream>
#include <cstring>
#include <cmath> // 引入cmath库以使用round()函数
using namespace std;

int main()
{
    FILE* fp_read = fopen("test1.txt", "r");
    FILE* fp_write = fopen("new.txt", "w");
    if (fp_read == NULL || fp_write == NULL)
    {
        perror("Can't open this file!");
        return -1;
    }
    char* array = new char[512]{ 0 }; //临时存放读出来的数据
    char temp = 0;                  //一个字符一个字符读
    int i = 0;                      //计数数组第几个
    while ((temp = fgetc(fp_read)) != EOF)
    {
        if (temp == '\n' || temp == ',')    //如果遇到了逗号或者换行,就说明一个有用的数据已经完整读出 
        {
            bool is_float = false;   //判断是否为浮点数
            int j;
            for (j = 0; j < i; j++)
            {
                if (array[j] == '.')
                {
                    is_float = true;    //是浮点数
                    break;
                }
            }
            if (is_float)    //如果是浮点数
            {
                double num = atof(array);
                num += 10.0;
                fprintf(fp_write, "%.*lf", i - j - 1, num);   //*是用来控制输出的小数位数
            }
            else    //如果是整数
            {
                double num = round(atof(array)); // 对浮点数进行四舍五入
                num += 10;
                fprintf(fp_write, "%d", (int)num); // 将四舍五入后的浮点数转换为整数并写入文件
            }
            i = 0;  //计数归零
            memset(array, 0, sizeof(array));  //清空数组
            fputc(temp, fp_write);
        }
        else if (temp >= 0)    //有用字符
        {
            array[i++] = temp;
        }
    }

    fclose(fp_read);
    fclose(fp_write);       //关闭文件
    delete[]array;         //释放空间
    return 0;
}

这样修改后,你的程序应该可以在x86系统上正常运行,且不会出现精度问题。