Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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
Java编译器文本到浮点值的转换与strod不同吗?_Java_Compiler Construction_Floating Point_Strtod - Fatal编程技术网

Java编译器文本到浮点值的转换与strod不同吗?

Java编译器文本到浮点值的转换与strod不同吗?,java,compiler-construction,floating-point,strtod,Java,Compiler Construction,Floating Point,Strtod,Java语言规范规定,浮点值按照IEEE 754标准的规定进行转换。对于strtod,C标准指定函数如何将文本转换为浮点值。关于陈述本身,两者似乎涵盖了相同的情况。我不确定的是,舍入规则怎么样?Java编译器所做的转换与strtod所做的不同吗 背景是,我想编译成Java字节码代码,因此需要将浮点/双精度值的文本表示转换为类文件中的表示 例如,此Java代码打印更精确的值: double value = 1.23412991913372577889911; System.out.println(

Java语言规范规定,浮点值按照IEEE 754标准的规定进行转换。对于strtod,C标准指定函数如何将文本转换为浮点值。关于陈述本身,两者似乎涵盖了相同的情况。我不确定的是,舍入规则怎么样?Java编译器所做的转换与strtod所做的不同吗

背景是,我想编译成Java字节码代码,因此需要将浮点/双精度值的文本表示转换为类文件中的表示

例如,此Java代码打印更精确的值:

double value = 1.23412991913372577889911;
System.out.println(value);
// Output: 1.2341299191337258
const char* textual = "1.23412991913372577889911";
double result = strtod(textual, ...);
std::cout << result << std::endl;
// Output: 1.23413
使用strtod转换相同的值并打印出来会打印出不太精确的值:

double value = 1.23412991913372577889911;
System.out.println(value);
// Output: 1.2341299191337258
const char* textual = "1.23412991913372577889911";
double result = strtod(textual, ...);
std::cout << result << std::endl;
// Output: 1.23413
const char*text=“1.23412991913372577889911”;
双重结果=标准文本(文本,…);

std::cout是的,存在差异。这里有两个我可以找到的

  • Java支持数字之间的下划线。根据规范:

    允许使用下划线作为表示整数部分的数字之间、表示分数部分的数字之间以及表示指数的数字之间的分隔符

    这对你来说应该不是问题。你只需要去掉所有的下划线

  • Java强制执行IEEE 754浮点算法的四舍五入规则。从(语言规范指的是
    Double.valueOf
    ):

    [该]精确数值然后在概念上转换为“无限精确”的二进制值,然后按照IEEE 754浮点算法的常用四舍五入至最接近规则四舍五入为double类型,其中包括保留零值的符号

    strtod
    的舍入模式由实现定义,IIUC甚至允许1 ULP的误差。根据C99规范(strtod文件参考第6.4.4.2节):

    对于十进制浮动常量,以及当FLT_基数不是2的幂时的十六进制浮动常量,结果是最近的可表示值,或以实现定义的方式选择与最近的可表示值相邻的较大或较小的可表示值

    仅当您的C编译器支持附录F:IEC 60559浮点运算时,
    strod
    才保证符合IEEE 754(IEC 60559和IEEE 754等效):

    浮点常量的转换时间转换以及中的strtod、strtof、strtold、fprintf、fscanf和相关库函数,并提供IEC 60559二进制十进制转换


  • 还要注意的是,
    strod
    仅从C99开始支持十六进制浮点表示法(Java从版本5开始)。所以,检查一下您的strtod的实现是如何运行的。

    您是否理解了这个问题?这是关于
    strod
    与Java编译器浮点转换的兼容性。不是关于将文本转换为浮点值。在您添加到示例中的代码段中,打印函数的行为不同,没有理由假设已解析不同的浮点值。@maxdev从在C上打印17位有效数字开始(实际上您的问题是“C”,但您的代码是C++)如果你想分辨出两者的区别,那就站在另一边
    printf(“%.16e”,…)
    正是这样做的。可能有一种方法可以在Java端以相同的格式打印浮点值,使比较更容易。或者将此方法用于
    cout
    std::cout Java的
    System.out.println
    打印“唯一标识浮点值所需的任意数字”。这使得与使用固定小数精度输出的打印函数的输出进行比较有点不方便。感谢您真正理解了这个问题并给出了非常好的答案。:)