【问题标题】:Does C have to calculate out a number in scientific notation?C是否必须以科学计数法计算出一个数字?
【发布时间】:2016-04-12 07:10:13
【问题描述】:

浮点数的最大值为 3.40282347E+38。这相当于 3.40282347 * 10^38。我想知道如果我设置一个等于这个的浮点数,它是否必须实际执行幂和乘法来获取要存储的值,或者科学记数法只是实际值?

我正在编写一个学校项目,我们正在尽最大努力对其进行优化,所以这与我有关,尤其是因为它位于嵌套循环结构中。

【问题讨论】:

  • 像这样的文字常量在编译时计算,而不是在运行时计算。此外,请使用 FLT_MAX 而不是硬编码的常量。
  • 好的,很高兴知道。我不允许包含 float.h 标头,所以我不能使用 FLT_MAX
  • 这也可能有帮助:stackoverflow.com/questions/3271588/…
  • “不能包含float.h...”这些奇怪的家庭作业规则有时让我质疑正在进行的教育...我可以理解告诉人们不要在作业中包含<unordered_map>是实现一个哈希表,但这很荒谬。
  • @DietrichEpp 我的猜测是一些更奇怪的规则是为了防止直接使用下载的软件作为家庭作业的答案。

标签: c floating-point scientific-notation


【解决方案1】:

当您在源代码中使用文字时,这些文字(主要是包含所有用于常量折叠的文字的表达式)在编译时进行评估并转换为诸如 move immediateadd immediatemove special_constant_register 等指令。

例如:

int a = 10, b = 0xA;

这里100xA 文字在编译时被评估为相同的值。在您的情况下,double 文字或 float 文字将在编译时进行评估,并将最合适的值分配给变量。

【讨论】:

    【解决方案2】:

    当您编写3.4e38 时,它会在编译时被完全评估。

    当你写3.4 * 10^38 时,你会得到一个完全出乎意料的结果。这是因为^ 在 C 中并不表示幂。它表示“异或”,而10 ^ 38 == 44。或者它根本没有编译,因为它被评估为(3.4 * 10) ^ 38,并且没有为浮点定义 xor。或者它是被定义的,所以它会是340 ^ 10

    【讨论】:

    • 谢谢,这只是伪代码。我的意思是 3.40282347 * pow(10, 38)
    【解决方案3】:

    这一切都在编译时完成。以下代码...

    #include <float.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void) {
      float foo = 3.40282347E+38;
      float bar = 3.40282347e38;
      printf("foo=%g\nbar=%g\n", foo, bar);
      return 0;
    }
    

    在汇编程序中产生这个。要让汇编器使用 -S 标志到 gcc 即,类似于

    gcc -S -Wall -O3 -pedantic -std=c11 scientific_notation.c 
    

    这是使用clang。我会剪断汇编程序...

     .section  __TEXT,__text,regular,pure_instructions
      .macosx_version_min 10, 11
      .section  __TEXT,__literal8,8byte_literals
      .align  3
    LCPI0_0:
      .quad 5183643170566569984     ## double 3.4028234663852886E+38
      .section  __TEXT,__text,regular,pure_instructions
      .globl  _main
      .align  4, 0x90
    

    ...剪掉了。

    注意这一行.quad 5183643170566569984。这是一个常数。另请注意,即使我的代码中有两个这样的常量,编译器也只需要一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-29
      • 2011-10-31
      • 2011-10-18
      相关资源
      最近更新 更多