9
\$\begingroup\$

Your task is to write a program, in any language, that adds two floating point numbers together WITHOUT using any fractional or floating point maths. Integer maths is allowed.

Format

The format for the numbers are strings containing 1's and 0's which represent the binary value of a IEEE 754 32-bit float. For example the number 2.54 would be represented by the string "01000000001000101000111101011100".

Goal

You program should input two numbers in the above mentioned format, add them together, and output the result in the same format. The shortest answer in any language wins!

Rules

Absolutly no floating point, decimal, or any kind of non-integer maths functions are allowed.

You can assume that the input is clean (i.e. contains only 1's and 0's).

You can assume that the inputs are numbers, and not Inf, -Inf, or NaN or subnormal. However, if the result is greater than the max value or smaller than the min value, you should return Inf and -Inf respectively. A subnormal (denormal) result may be flushed to 0.

You do not have to handle rounding properly. Don't worry if your results are a few bits out.

Tests

To test your programs, you can convert between decimal and floating point binary numbers using this tool.

1000 + 0.5 = 1000.5

01000100011110100000000000000000 + 00111111000000000000000000000000 = 01000100011110100010000000000000

float.MaxValue + float.MaxValue = Infinity

01111111011111111111111111111111 + 01111111011111111111111111111111 = 01111111100000000000000000000000

321.123 + -123.321 = 197.802

01000011101000001000111110111110 + 11000010111101101010010001011010= 01000011010001011100110101010000

Good luck!

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Python, 224 chars

This code converts a floating point input f to the integer f*2^150, does the addition using python native big integers, then converts back.

V=lambda x:((-1)**int(x[0])<<int(x[1:9],2))*int('1'+x[9:],2)
B=lambda x,n:B(x/2,n-1)+'01'[x&1]if n else''
def A(x,y):
 v=V(x)+V(y)
 s=e=0
 if v<0:s=1;v=-v
 while v>=1<<24:v/=2;e+=1
 if e>254:v=0
 return'%d'%s+B(e,8)+B(v,23)
\$\endgroup\$
3
\$\begingroup\$

J (172 characters)

Since IEEE 754 allows five rounding rules, I chose the "toward 0" rule. Here is my code:

b=:(_1&^)@".@{.*[:#.1x,("."0)@(9&}.),#.@:("."0)@}.@(9&{.)$0:
a=:b@[([:,(<&0)":"0@:,,@((8$2)&#:)@(-&24)@$@#:,}.@(24&{.)@#:@|)@(]`(**2x^278"_)@.((>&((2x^278)-2x^254))@|))@+b@]

The very same examples you give (but not exactly the same results because of the different rounding rule):

   '01000100011110100000000000000000' a '00111111000000000000000000000000'
01000100011110100010000000000000
   '01111111011111111111111111111111' a '01111111011111111111111111111111'
01111111100000000000000000000000
   '01000011101000001000111110111110' a '11000010111101101010010001011010'
01000011010001011100110101001111
\$\endgroup\$

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