6 ms·
> Since floating point units were so slow, why did the C language end up with float and double types ? After all, the machine used to invent the language (PDP-1
by makmanalp 9y ago
> Since floating point units were so slow, why did the C language end up with float and double types ? After all, the machine used to invent the language (PDP-11) did not have a floating point unit! The manufacturer (DEC) had promised to Dennis Ritchie and Ken Thompson the next model would have one. Being astronomy enthusiasts they decided to add those two types to their language.
Wait, what was the alternative? No floats? How the heck would people calculate things with only integers?
edit: AFAIK bignums are even slower, and fixed-point accumulates error like crazy
- coldtea 9y ago>How the heck would people calculate things with only integers? Easily -- it happens all the time in industries which demand specific precision -- e.g. integers are used to calculate monetary values in languages that don't have a decimal/big number type. You just need to format them to the precision you want when you show them to the user. It would just be slow.
- makmanalp 9y agoSorry, by bignum I didn't mean "big numbers", I meant arbitrary-precision, i.e. 1/3 instead of 0.333333333, is this what you mean? I don't see how you get around stuff like many divisions or nth roots. You'd lose precision during the calculation operation, right? Whether you format it at the end has little bearing, since it'll be garbage by that time.
- pjc50 9y agoYou can just as easily lose precision in FP arithmetic if you're not careful. But for engineering purposes fixed point works quite well because having arithmetic much more precise than manufacturing tolerance is no use. Fixed point was good enough to go to the moon: https://www.netjeff.com/humor/item.cgi?file=ApolloComputer https://www.netjeff.com/humor/item.cgi?file=ApolloComputer
- makmanalp 9y agoAND core-rope memory. Wow. Thank you for this.
- deleted 9y ago[deleted]
- coldtea 9y ago>I meant arbitrary-precision, i.e. 1/3 instead of 0.333333333, is this what you mean? No, more like having in mind the precision you want and multiplying with that (scaling your number, so to speak). But that's for fixed precision -- it just gives you access to decimal values. (You could emulate arbitrary precision in software too, but it would be way slower). >You'd lose precision during the calculation operation, right? Yes, but that's the case with FP too. You can't just use floats for financial calculations for example.
- deleted 9y ago[deleted]
- mivanchev 9y ago>Wait, what was the alternative? No floats? How the heck would people calculate things with only integers? I find working with fixed-point numbers actually much easier than (hardware) floats, because of the even distribution. Also note that some libraries like OpenGL ES provide fixed-point types for extra performance. I do believe IEEE 754 is next to impossible to use for any practical application, unless all your values are between -1 and 1. It's truly a horrible standard.
- photojosh 9y agoEmbedded developer here, using 8-bit microcontrollers, so all our calculations are done in fixed-point/integers. Here's a chunk of real code that converts results from the analog-digital converter to appropriate units. A lot of precalculated constants and things like using shifts instead of division as much as possible. // - motor current from ACS723 (2.5V is 0A, +/- 400mV/A) ADC_SET_MUX(motor_current_in_adc); ADC_START(); while (ADC_RUNNING()) {} uint8_t result_current = ADCH; // result(val) * 5V/256(val) * 1000mA/0.4V => result*48.828 = current in ma // e.g. 5A -> 4.5V out = 230, less 2.5V (128) = 102 // 102 * 48.828125 = 4980 mA // for max precision, max multiplier = 32678/128 = 255, // use (value * (48.828 << 2)) >> 2. -> 195 // value_ma = (result_adc * 195) >> 2 current_ma = (((int16_t)(result_current) -127) * 195) >> 2; // - motor output speed feedback signal (filtered PWM, 16% (1/6.1) of actual value, so 5V in == 30.5V) ADC_SET_MUX(motor_speed_fb_adc); ADC_START(); while (ADC_RUNNING()) {} uint8_t result_speed = ADCH; // result(val) * 6.1 = actual speed setting // result / 256 * 6100 = actual in mV int16_t speed_mv = (uint16_t) result_speed * 119; #if DEBUG // calculate target speed mv uint16_t output_speed_mv = ((uint16_t) motor_current_speed * 195) >> 2; #endif
- makmanalp 9y agoThis is exactly what I was imagining! x>>2 rather than x/2. Brilliant, thanks.
- esmi 9y agoI've definitely read a ton of code like this. I often do it in simulation as well to help speed up calculations. Basically one is still doing floating point, but manually. i.e. You changed the unit (a.k.a. exponent a.k.a. window) such that the desired value can be accurately quantized by an unsigned int (a.k.a. mantissa a.k.a offset). The big caveat being one needs to be sure the calculation doesn't over/under flow the window, of course.
- sprash 9y agoA logarithmic number system is in my opinion far superior to floating point in many ways. https://en.wikipedia.org/wiki/Logarithmic_number_system https://en.wikipedia.org/wiki/Logarithmic_number_system