2

My question is simple: I can do 2 * 10 with shift and addition by (2 << 2) + 2 but I have no idea how to get 2.2 * 10 with shift and addition. Any suggestions will be very appreciated.

-khan_gl

Mysticial
  • 464,885
  • 45
  • 335
  • 332
abe
  • 31
  • 1
  • If you are using double or float as I think, you can't simply. The binary representation of floating point number is a standardish nightmare. If you can deal with fixed point numbers, then it's easy. – J.N. Mar 08 '12 at 04:36
  • Somewhat Related: http://stackoverflow.com/questions/7720668/fast-multiplication-division-by-2-for-floats-and-doubles-c-c – Mysticial Mar 08 '12 at 04:50
  • @BLUEPIXY: `(x << 3) + (x << 2)` is `x * 12`, not `x * 012`. – Alexey Frunze Mar 08 '12 at 08:43
  • oh! misstake. (*10) is (x << 3) + (x << 1) – BLUEPIXY Mar 08 '12 at 18:34

3 Answers3

2

This works:

2.2 + 2.2 + 2.2 + 2.2 + 2.2 + 2.2 + 2.2 + 2.2 + 2.2 + 2.2 + (0 << 1)

Kidding aside, you can't as you can't shift floats in C++/C. Well, you can (via nasty type-punning), but then you're getting into undefined behavior.

Also, there's no point in doing it. If you're doing multiplication then just use *. The compiler will transform it into the most efficient form.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Pubby
  • 51,882
  • 13
  • 139
  • 180
  • What's `0 << 1` for? I don't think it's UB, the standard requires integer operands for shift operators. – Alexey Frunze Mar 08 '12 at 04:47
  • @Alex khan wanted a shift in there so I complied ;) The UB comes from casting the float to an int to perform the shift. – Pubby Mar 08 '12 at 04:50
  • @Pubby: I see no undefined behavior. There is no *cast* from `float` to `int`. `(0 << 1)` is of type `int`, with the value 0. The result is implicitly converted from `int` to `double` (not `float`), which yields `0.0`. What problem do you see? – Keith Thompson Mar 08 '12 at 04:52
  • @KeithThompson Ah, guess it must be with type punning then. My example wasn't meant to show UB. – Pubby Mar 08 '12 at 04:57
  • @Pubby: I think I see what you mean; you're talking about something like `*(unsigned*)&float_object << 1`, which certainly is UB. I'm going to update your answer to make that clearer. – Keith Thompson Mar 08 '12 at 04:59
1

If I understood your question at all,

2.2 = 2 + 2/10

Therefore, 2.2 * 10 = 2*10 + 2*10/10 = 2*10 + 2 = 22.

You can do division with shifts and subtractions.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
1

On a modern CPU, floating point numbers are represented in a format called "IEEE 754".

At the core of IEEE 754 floating point arithmetic are bit shifts and integer arithmetics. If you're patient you can write a naive implementation of IEEE 754 ALU in C. You might find this thread interesting:

Community
  • 1
  • 1
nodakai
  • 7,773
  • 3
  • 30
  • 60