2017-01-27 13 views
-1

Мне было поручено воссоздать printf в C, не используя внешние библиотеки. Я пытаюсь реализовать функциональность% f с точностью до 6 знаков после запятой. Поэтому в основном, если я передаю 15.2554 в функцию printf, «15.255400» должен быть напечатан. Вместо этого напечатано «15.255399». Мой код, чтобы найти знаков после запятой реализован как таковой:Ошибка округления при преобразовании Double to Char

print_function(double input){ 

    int i = 0; 
    int temp; 
    double temp_dub; 
    char temp_char; 

    temp = (int)input; 

    temp_dub = input - temp; 

    while (i < 6){ 

    temp_dub = temp_dub * 10; 
    temp = (int) temp_dub; 
    temp_char = (char) (temp+48) 

    write(1,&temp_char,1); 
    i++; 

    temp_dub -= (int) temp_dub; 
    } 

    return; 
} 

Может кто-нибудь пожалуйста, осветить меня, почему я не могу получить конечные нули и вместо того, чтобы это число чуть ниже моего входа 15.554?

+1

'C' и' C++ '** разные ** языки. Один тег явно не нужен. – Ari0nhh

+0

В вашей функции отображается мусор для 15.554. Убедитесь, что вы разместили правильный фрагмент кода. – DyZ

+0

Этот код может работать на C или C++, если я не ошибаюсь. – Heisenberg

ответ

2

Значение 15.2554 не представляется в виде двоичного кода64 (IEEE-754 double). Вы можете увидеть, если вы печатаете вход с достаточным количеством цифр:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
// I took the liberty to implement Ari0nhh's changes here 
void print_function(double input){ 
    int i = 0; 
    int temp; 
    double temp_dub; 
    char temp_char; 

    temp = (int)input; 
    temp_dub = input - temp; 

    while (i < 6){ 
    temp_dub = temp_dub * 10; 
    temp = (int) temp_dub; 
    temp_char = (char) (temp + 48); 
    write(1,&temp_char,1); 
    i++; 
    temp_dub -= (int) temp_dub; 
    } 
} 

int main(int argc, char **argv){ 
    double input; 
    if(argc != 2){ 
    fprintf(stderr,"Usage: %s float\n",argv[0]); 
    exit(EXIT_FAILURE); 
    } 
    // checks omitted 
    input = strtod(argv[1],NULL); 
    printf("INP %.20g\n",input); 
    print_function(input); 
    putchar('\n'); 
    exit(EXIT_SUCCESS); 
} 

Вы увидите, что 15.2554 отпечатки, как 15.255399999999999849. Так что вам нужно крутить вручную здесь, извините.

+0

Хорошо, это имеет смысл, но тогда как я смогу округлить, если я попытаюсь написать функцию printf самостоятельно? Как я узнаю, что я получаю только 4 места точности и нужно округлить последние два, если двоичный код показывает большую точность? – Heisenberg

+1

Вы не можете, эта информация будет потеряна. На вещи, которую вы можете сделать, нужно всегда проверять 7-ю цифру и раунд (в любом режиме округления, который вы предпочитаете). – deamentiaemundi

+0

Благодарим за ответ и не забираем, правильно ли я помечал вещи! – Heisenberg