7

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?

Xandros
  • 727
  • 1
  • 9
  • 21
  • 1
    Sure, why don't you take a look at an implementation of `printf`? – Oliver Charlesworth May 16 '15 at 20:01
  • Or one of them, for example `glibc`'s since it's source code is available for download. – Iharob Al Asimi May 16 '15 at 20:02
  • possible duplicate of [source code of c/c++ functions](http://stackoverflow.com/questions/1127328/source-code-of-c-c-functions) – Ed Heal May 16 '15 at 20:05
  • Perhaps [an oldie](http://stackoverflow.com/questions/2404675/how-do-i-convert-from-a-decimal-number-to-ieee-754-single-precision-floating-poi) that does the reverse may help. – Jongware May 16 '15 at 20:09
  • Depends on what rules you make for printing them (fixed number of decimals? decimal number completely equivalent in value? shortest string for which it is unambiguous which float it represents?). You could try [this one](http://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf) and do a lot better than most current implementations. – harold May 16 '15 at 20:10
  • 1
    See the classic SIGPLAN article, "How to Print Floating-Point Numbers Accurately", https://lists.nongnu.org/archive/html/gcl-devel/2012-10/pdfkieTlklRzN.pdf – Jerry101 May 16 '15 at 20:31
  • 1
    See http://www.netlib.org/fp/dtoa.c – lhf May 17 '15 at 03:13

2 Answers2

6

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/

Simon Byrne
  • 7,694
  • 1
  • 26
  • 50
3

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

mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
  • 4
    No, this cannot be used as the basis for a proper function. It is only a dirty hack, and to move from it to something that works correctly one needs to throw this one away. In your defense, to implement a proper binary-to-decimal in C from scratch one basically needs to start by implementing an at least rudimentary bignum library (http://www.openwall.com/lists/musl/2012/04/10/6 ) but if one does not want to do the correct version, one can at least do http://www.opensource.apple.com/source/ruby/ruby-18/ruby/missing/strtod.c?txt . And read http://www.exploringbinary.com/ of couse. – Pascal Cuoq May 17 '15 at 00:04