Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do languages handle printing floats under the hood?

As a personal project, I have been writing a compiler for my own C like language to target a CPU emulator of my own design.

As a part of this, I want to implement a standard floating point library (typical IEEE single precision), but I've been struggling to think of a way to print out floats in an easy to read way (as in 1.2345 rather than the raw data integer), the best I could think of is generating values for log102 and doing some odd multiplications to get the number in a suitable form for printing.

Is there an algorithm for converting a float to an easily printable form, or for printing a float which can be implemented without using printf("%f",float_value); or type castings in a C like language?

like image 758
Xandros Avatar asked May 16 '15 19:05

Xandros


2 Answers

As I understand, the current state of the art for printing floating point numbers is the Grisu family of algorithms, by Florian Loitsch. You can read the paper here.

For a somewhat easier introduction to the issues in converting binary floating point to decimal (and vice-versa), I thoroughly recommend Rick Regan's site, http://www.exploringbinary.com/

like image 116
Simon Byrne Avatar answered Sep 27 '22 20:09

Simon Byrne


It may be a dirty hack of a function, but you may use this as a basis for a function to properly display floating point numbers. It doesn't use any other auxiliary function, apart from putchar to actually print something, and it doesn't cover all situations (like your number being a NaN, or even being a negative!) but, well, it's just a starting point:

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

You can test it here: http://goo.gl/V4pgNZ

like image 30
mcleod_ideafix Avatar answered Sep 27 '22 20:09

mcleod_ideafix