2010-08-16 3 views
17

я хотел преобразовать двойной плавать в C, но хотел сохранить десятичную точку точно, насколько это возможно без каких-либо изменений ...C: преобразование двойной плавать, сохраняя десятичную Точность точки

, например, скажем, я have

double d = 0.1108; 
    double dd = 639728.170000; 
    double ddd = 345.2345678 

теперь исправьте меня, если я ошибаюсь, я знаю, что точность с плавающей запятой составляет около 5 чисел после точки. могу ли я получить эти пять чисел после точки точно так же, как у двойника? так что приведенные выше результаты следующим образом:

float f = x(d); 
    float ff = x(dd); 
    float fff = x(ddd); 

    printf("%f\n%f\n%f\n", f, ff, fff); 

он должен напечатать

0.1108 
    639728.17000 
    345.23456 

все цифры после предела точности (которые я считать, как 5) будет усечена.

+8

с плавающей точкой точность более точно указана как «число значащих цифр», а не «номер цифр после запятой ». 12345678.12345, скорее всего, не будет точно отображаться с помощью поплавка. –

+8

Помимо недоразумений относительно представления чисел с плавающей запятой, которые были прокомментированы и ответили, функция 'x', которую вы ищете, - это бросок из double в float' (float) '. Если вы не изменили режим округления по умолчанию по умолчанию, то этот лимит вычисляет 'float', который ближе всего к' double', который вы конвертируете. Нет лучшего преобразования, чем этот, поэтому, если он потеряет слишком много точности для вашего вкуса, держите свои «двойники» такими, какие они есть. –

+2

Усечение - это не самый точный способ их преобразования - 345.2345678 находится ближе к 345.23457, чем к 345.23456 – caf

ответ

26

float и double не хранят знаки после запятой. Они хранят двоичный код: float (предположительно IEEE 754) 24 значащих бита (7,22 десятичных разряда), а double - 53 значащих бита (15,95 значащих цифр).

Преобразование из double в float даст вам самое ближайшее сообщение float, так что округление не поможет вам. Другое дело может дать вам «шумные» цифры в десятичном представлении.

#include <stdio.h> 

int main(void) { 
    double orig = 12345.67; 
    float f = (float) orig; 
    printf("%.17g\n", f); // prints 12345.669921875 
    return 0; 
} 

Чтобы получить double приближение к славному десятичного значения вы предназначенным, вы можете написать что-то вроде:

double round_to_decimal(float f) { 
    char buf[42]; 
    sprintf(buf, "%.7g", f); // round to 7 decimal digits 
    return atof(buf); 
} 
+0

@ davidvandebunte: Это только на C++. Вопрос помечен как C. – dan04

11

A float обычно имеет около 7 цифр точности, независимо от положения десятичной точки. Поэтому, если вам нужно 5 цифр точности после десятичного знака, вам нужно ограничить диапазон чисел меньше чем где-то около +/- 100.

-1

Числа с плавающей запятой представлены в научной нотации как число из семи значащих цифр, умноженное на большее число, которое представляет собой место десятичной точки. Более подробная информация об этом в Википедии:

http://en.wikipedia.org/wiki/Floating_point