2015-05-16 4 views
7

Как персональный проект, я пишу компилятор для своего собственного C-подобного языка, чтобы настроить эмулятор процессора моего собственного дизайна.Как языки обрабатывают печать поплавков под капотом?

В качестве части этого я хочу внедрить стандартную библиотеку с плавающей запятой (типичная одиночная точность IEEE), но я изо всех сил пытаюсь придумать способ распечатать поплавки в удобном для чтения способом (как в 1.2345, а не целое число необработанных данных), лучшее, что я мог подумать, - это генерировать значения для журнала 2 и делать некоторые нечетные умножения, чтобы получить номер в подходящей форме для печати.

Есть ли алгоритм преобразования поплавка в легкодоступную для печати форму или для печати поплавка, который может быть реализован без использования printf("%f",float_value); или типа отливок на C-подобном языке?

+1

Конечно, почему бы вам не взглянуть на реализации 'printf'? –

+0

Или один из них, например 'glibc', так как это исходный код, доступен для скачивания. –

+0

Возможный дубликат [исходный код функций c/C++] (http://stackoverflow.com/questions/1127328/source-code-of-cc-functions) –

ответ

3

Это может быть грязный взломать функцию, но вы можете использовать ее как основу для правильной отображения чисел с плавающей запятой. Он не использует никакой другой вспомогательной функции, кроме putchar, чтобы на самом деле печатать что-то, и она не охватывает все ситуации (например, ваш номер является NaN или даже является отрицательным!), Но, ну, это просто отправная точка :

#include <stdio.h> 

void printfloat (float n) 
{ 
    int whole = n; 
    int power = 1; 
    int digit; 

    /* Find out the largest divisor for printing the integer part */ 
    while (whole>=1) 
    { 
     whole /= 10; 
     power *= 10; 
    } 
    power /= 10; 

    /* Prints the integer part of the number */ 
    whole = n; 
    while (power>=1) 
    { 
     digit = whole/power; 
     whole %= power; 
     putchar ('0'+digit); 
     power /= 10; 
    } 

    /* Prints the decimal point */ 
    putchar ('.'); 

    /* And now the fractional part */ 
    n = n-(int)n; 
    while(n!=0) 
    { 
     digit = n*10; 
     putchar ('0'+digit); 
     n*=10; 
     n = n-(int)n; 
    } 
    putchar ('\n'); 
} 

int main() 
{ 
    float n = 123.45678; 

    printfloat(n); 
    return 0; 
} 

Вы можете проверить его здесь: http://goo.gl/V4pgNZ

+3

Нет, это не может быть использовано в качестве основы для правильной функции. Это всего лишь грязный хак, и чтобы перейти от него к чему-то, что работает правильно, нужно выбросить его. В вашей защите, чтобы реализовать правильное двоичное-десятичное значение в C с нуля, вначале нужно начать с реализации, по крайней мере, рудиментарной библиотеки bignum (http://www.openwall.com/lists/musl/2012/04/10/6), но если вы не хотите делать правильную версию, вы можете, по крайней мере, выполнить http://www.opensource.apple.com/source/ruby/ruby-18/ruby/missing/strtod.c?txt. И прочитайте http://www.exploringbinary.com/ of couse. –

6

Как я понимаю, современное состояние техники для печати чисел с плавающей точкой является семейство Grisu алгоритмов, Флориан Loitsch. Вы можете прочитать статью here.

Для несколько проще введения к проблемам в преобразовании двоичной плавающей точки в десятичной (и наоборот), я очень рекомендую сайт Рика Риган, http://www.exploringbinary.com/

Смежные вопросы