简体   繁体   English

C是否必须用科学计数法计算出一个数字?

[英]Does C have to calculate out a number in scientific notation?

The max value of a float is 3.40282347E+38. 浮点数的最大值是3.40282347E + 38。 This is equivalent to 3.40282347 * 10^38. 这相当于3.40282347 * 10 ^ 38。 I am wondering if I set a float equal to this, does it have to actually perform the power and multiplication to get the value to store, or is scientific notation simply the actual value? 我想知道我是否设置了一个与此相等的浮点数,它是否必须实际执行幂和乘法才能得到存储的值,或者科学记数法只是实际值?

I am writing a school project in which we are optimizing as best we can, so this is relevant to me, especially since it is within a nested loop structure. 我正在编写一个我们正在优化的学校项目,所以这对我来说很重要,特别是因为它在嵌套的循环结构中。

When you use literals in your source code, those literals (and mostly expression containing all literals for constant folding) are evaluated at compile time and converted to instructions like move immediate , add immediate , move special_constant_register etc. 当您在源代码中使用文字时,这些文字(以及主要用于常量折叠的所有文字的表达式)在编译时进行评估,并转换为move immediate add immediatemove special_constant_register等指令。

For ex: 例如:

int a = 10, b = 0xA;

Here both 10 and 0xA literals are evaluated to same value at compile time. 这里, 100xA文字在编译时被计算为相同的值。 In your case also, double literal or float literal would be evaluated at compile time and most appropriate value would be assigned to the variable. 在您的情况下,也会在编译时评估double literal或float literal,并为该变量分配最合适的值。

When you write 3.4e38 , it is completely evaluated at compile-time. 当你编写3.4e38 ,它会在编译时完全评估。

When you write 3.4 * 10^38 , you get a completely unexpected result. 当你写3.4 * 10^38 ,你会得到一个完全出乎意料的结果。 This is because ^ does not mean power-of in C. It means “exclusive or”, and 10 ^ 38 == 44 . 这是因为^并不意味着C中的幂。它意味着“异或”,并且10 ^ 38 == 44 Or maybe it doesn't compile at all, because it is evaluated as (3.4 * 10) ^ 38 , and xor is not defined for floating points. 或者它可能根本不编译,因为它被评估为(3.4 * 10) ^ 38 ,并且没有为浮点定义xor。 Or it is defined, so it would be 340 ^ 10 . 或者它被定义,所以它将是340 ^ 10

It's all done at compile time. 这一切都是在编译时完成的。 The following code... 以下代码......

#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;
}

Produces this in assembler. 在汇编程序中生成它。 To get the assembler use the -S flag to gcc ie, something like 为了让汇编程序使用-S标志来表示gcc,例如

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

This is using clang. 这是使用clang。 I'll snip the assembler a bit... 我会稍微剪掉汇编程序......

 .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

...snipped. ...剪断。

Note this line .quad 5183643170566569984 . 请注意这一行.quad 5183643170566569984 It's a constant. 这是一个常数。 Also note that even though I have two of these constants in my code only one is needed by the compiler. 另请注意,即使我的代码中有两个这样的常量,编译器也只需要一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM