【问题标题】:Rounding Error When Converting Double to Char将 Double 转换为 Char 时出现舍入错误
【发布时间】:2017-01-27 03:35:47
【问题描述】:

我的任务是不使用外部库在 C 中重新创建 printf。我正在尝试以 6 位小数的精度实现 %f 功能。所以基本上,如果我将 15.2554 传递给 printf 函数,应该打印“15.255400”。相反,打印的是“15.255399”。我的查找小数位的代码是这样实现的:

print_function(double input){

  int i = 0;
  int temp;
  double temp_dub;
  char temp_char;

  temp = (int)input;

  temp_dub = input - temp;

  while (i < 6){

    temp_dub = temp_dub * 10;
    temp = (int) temp_dub;
    temp_char = (char) (temp+48)

    write(1,&temp_char,1);
    i++;

    temp_dub -= (int) temp_dub;
  }

  return;
}

谁能告诉我为什么我无法得到尾随零,而是这个数字略低于我输入的 15.554?

【问题讨论】:

  • CC++不同的语言。显然不需要一个标签。
  • 您的函数显示 15.554 的垃圾。确保您发布了正确的代码 sn-p。
  • 除非我弄错了,否则这段代码可以在 C 或 C++ 中运行。
  • DYZ。这个确切的代码在我的机器上工作并打印出 15.255399 而不是 15.255400
  • 至少,您的代码不会打印任何句点。再检查一遍。如果您按照 Ari0nhh 的答案中的建议进行更改,它起作用。 (48 应该添加到 temp_char,而不是 temp。)

标签: c char int double


【解决方案1】:

15.2554 不能表示为二进制64 (IEEE-754 double)。如果您使用足够的数字打印输入,您可以看到它:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// I took the liberty to implement Ari0nhh's changes here
void print_function(double input){
  int i = 0;
  int temp;
  double temp_dub;
  char temp_char;

  temp = (int)input;
  temp_dub = input - temp;

  while (i < 6){
    temp_dub = temp_dub * 10;
    temp = (int) temp_dub;
    temp_char = (char) (temp + 48);
    write(1,&temp_char,1);
    i++;
    temp_dub -= (int) temp_dub;
  }
}

int main(int argc, char **argv){
  double input;
  if(argc != 2){
    fprintf(stderr,"Usage: %s float\n",argv[0]);
    exit(EXIT_FAILURE);
  }
  // checks omitted
  input = strtod(argv[1],NULL);
  printf("INP %.20g\n",input);
  print_function(input);
  putchar('\n');
  exit(EXIT_SUCCESS);
}

您将看到15.2554 打印为15.255399999999999849。所以这里需要手动取整,抱歉。

【讨论】:

  • 好的,这是有道理的,但是如果我自己尝试编写 printf 函数,我将如何进行舍入呢?如果二进制显示出更高的精度,我怎么知道我只收到了 4 个位置的精度并且需要对最后两个进行舍入?
  • 您不能,该信息已丢失。您可以做的就是检查第 7 位数字并始终进行舍入(以您喜欢的任何舍入模式)。
  • 感谢您对我是否正确标记事物的回答而不是挑剔!
猜你喜欢
  • 2014-06-15
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 2022-12-08
  • 2012-05-04
  • 2013-11-28
相关资源
最近更新 更多