2016-04-12 13 views
3

Максимальное значение поплавка - 3.40282347E + 38. Это эквивалентно 3,40282347 * 10^38. Я задаюсь вопросом, устанавливаю ли я поплавок, равный этому, действительно ли он должен выполнять мощность и умножение, чтобы получить значение для хранения, или научное обозначение просто фактическое значение?Нужно ли C рассчитать число в научной нотации?

Я пишу школьный проект, в котором мы оптимизируем как можно лучше, поэтому это имеет отношение ко мне, тем более, что оно находится внутри структуры вложенных циклов.

+1

Литеральные константы, такие как это, оцениваются во время компиляции, а не во время выполнения. Кроме того, используйте 'FLT_MAX', а не жестко закодированную константу. –

+0

нормально, отлично знать. Мне не разрешено включать заголовок float.h, поэтому я не могу использовать FLT_MAX – FLOWMEEN

+0

Это также может помочь: http://stackoverflow.com/questions/3271588/representation-of-float-in-c – RhinoDevel

ответ

1

При использовании литералов в исходном коде, эти литералы (и в основном выражение, содержащее все литералы для постоянного складывания) оценивается во время компиляции и преобразуется в инструкцию, как move immediate, add immediate, и т.д.

Для экс:

int a = 10, b = 0xA; 

Здесь оба 10 и 0xA литералов оцениваются с одинаковым значением во время компиляции. В вашем случае также, double literal или float literal будет оцениваться во время компиляции, и наиболее подходящее значение будет присвоено переменной.

1

Когда вы пишете 3.4e38, он полностью оценивается во время компиляции.

Когда вы пишете 3.4 * 10^38, вы получаете совершенно неожиданный результат. Это связано с тем, что ^ не означает мощность в C. Это означает «эксклюзивный» или «10^38 == 44». Или, может быть, он вообще не компилируется, потому что он оценивается как (3.4 * 10)^38, а xor не определен для плавающих точек. Или это определено, поэтому было бы 340^10.

+0

спасибо, это был просто псевдокод. Я имел в виду 3.40282347 * pow (10, 38) – FLOWMEEN

1

Это все сделано во время компиляции. Следующий код ...

#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 

Этого использования лязга. Я немного отрежусь от ассемблера ...

.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. Это постоянный. Также обратите внимание, что хотя у меня есть две из этих констант в моем коде, только компилятор нужен только одному.