0

I am trying to build a class where user can compute floating operations with a particular accuracy. For example, if the user wants to have up to 4 digit accuracy, everything less than 0.0001 is zero and everything bigger than 9999 is inf.

I think the best way is to create a bit (or maybe byte) array to store sign, mantissa and exponent. For istance, with 4 (decimal) digits accuracy I could calculate how many bits I would need to store smallest and biggest value and then create array of that size.

This leads me to two of my questions :

  1. Why does single precision use exactly 8 bits for the exponent and 24 for the mantissa (IEEE 754) rather than 10 and 53, or 12 and 51? Is it somehow relevant or is it just a standard?
  2. Assuming I need 4 digit precision for 9999, I would need 14 bits but how much space do I need to keep 0.0001 in 4 (decimal) digit accuracy?

If the answer for the 1st question is "it is just a standard" I have yet another question :

  • How do I choose the best exponent and mantissa for my problem?

Please disregard the fact numbers bigger and smaller might be calculated here as I will just 'if' them out. I do not want to use double/float/etc for this I need as I expect to use more memory than a double would need but I do not want to use too much space.

  • 3
    Re: "User want to have up to 4 numbers accuracy thus everything less than 0.0001 is zero and bigger than 9999 is inf." That does not sound like floating point. A floating point data type with four decimal digits of accuracy could represent the number 0.00000004321 or the number 432100000000. What it would not be able to represent is a number like 1234.4321 because that would require eight digits of precision. – Solomon Slow Mar 15 '16 at 20:25
  • 1
    If you are creating your own floating point system, and you require it to have an exact number of decimal digits, then why make it binary? Why not use a decimal representation? – Solomon Slow Mar 15 '16 at 20:27
  • @james Well, yes you are right I haven't thought this through. So, should I do 8 numbers accuracy as max number = 99999999 ? This task is created by me to prove some point - i want to create this class on run time (not really relevant for it). – MaLiN2223 Mar 15 '16 at 20:40
  • There are libraries in existence to do this already. What is this for and for what platform? – whatsisname Mar 15 '16 at 20:44
  • 2
    The problem you presented is, IMO, best solved with a fixed-point system with 4 digits before the decimal point and 4 digits after it. – James Youngman Mar 15 '16 at 20:46
6

Implementing Your Number System

I am trying to build a class where user can compute floating operations with a particular accuracy. For example, if the user wants to have up to 4 digit accuracy, everything less than 0.0001 is zero and everything bigger than 9999 is inf.

If you require there to be a specific (maximum) number of digits after the decimal point, then the sytem you're describing is a fixed-point system, as opposed to a floating-point system.

A simple way to implement such a system is to store the numbers as integers, scaled up by a scaling factor of 10000. Hence, the (internal) value 20000 would represent 2.0000. Hence the arithmetic operations (add/subtract/multiply/divide) can all be implemented directly on the internal value. For multiplication, you would need to divide by the scaling factor after multiplying the internal values. For division, you should multiply the numerator before performing the division.

Since 10000 represents 1.0000 and you want to store values up to 9999.0000, then the largest internal value you want to store would be 99990000. log2(99990000) is just under 27 so a 32-bit-wide integer would be sufficient for that. However, you will need to use a wider type (64 bits for example) for intermediate values when multiplying and dividing.

See also What's the best way to do fixed-point math? on stackoverflow.

Why 8 bits of Exponent for float?

8 bits of exponent provides for numbers upu to around 1.0e38. I think the reason that float and double use this number of exponent digits is simply that most actual calculations don't involve quantities larger than this. There are physically-relevant numbers bigger than this (the Eddington number, for example, but I guess they just don't turn up that often in calculations. For most real (pun intended!) applications, if you have an extra bit available, you benefit more from using it in the mantissa.

If you have many more binary digits, say twice as many, you can add 29 bits to the mantissa and 3 bits to the exponent (favouring, as I mentioned, the mantissa). This allows you to deal with values in the approximate range 1e-308 .. 1e308. I don't recall ever needing to do a computation with a quantity larger than that. But there are specialist implementations available for such cases (such as CLN).

You might also find it helpful to read the Wikipedia article on IEEE 754.

  • 1
    For the origin of the IEEE-754 floating-point formats and the rationale behind them, you may also want to look at this answer plus my comments. – njuffa Mar 31 '16 at 18:04
1

Single precision uses a total of 32 bits and not 64 bits because it is single precision. Using 10+52 bits wouldn't exactly save much memory compared to double precision.

If you ask why 8 + 24 bits for exponent / mantissa: They wanted to use 32 bits. So any combination that adds up to 32 goes. Would you like 24 bit exponent and 8 bits mantissa? Not very useful, not enough precision. 8 bits exponent gives a range to 10^+/-38. You could maybe go with 7 bits, but 6 bits would only give you a few billions. Not enough.

It's a reasonable compromise. Not everyone will agree that it is optimal, but everyone will agree that it is close.

  • IEEE floating point maths was designed to work well on machines that have 8-bit bytes, and word lengths that are a power of 2 - that is 1, 2, 4 or 8 bytes (8, 16, 32 or 64 bits). So a single precision float is exactly 32 bits, and a double precision one is 64 bits. – Simon B Mar 31 '16 at 10:22
  • Extended precision uses 80 bits. Not a power of two. IEEE floating point would have worked with any number of bits for a floating point number (within reason; GPU hardware often supports 16 bit but not less), just a matter of dividing up exponent and mantissa. – gnasher729 Mar 31 '16 at 14:41
  • The x87 extended precision format (there are others - IBM uses 128 bits) isn't a power-of-two length, but it's a 16 + 64 bit format. This is no coincidence, the 64 bit significand lends itself to convenient integer operations using 64 bit registers. The next logical size would be 32+64, and there's just not enough reason to have numbers as big as 1.0E+357913941 (!) – MSalters Mar 31 '16 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.