7 ms·
What you're describing is called fixed point arithmetic, a super cool technique I wish more programmers knew about. Proper finance related code should use it,
by dajoh 2y ago
What you're describing is called fixed point arithmetic, a super cool technique I wish more programmers knew about.
Proper finance related code should use it, but in my experience in that industry it doesn't seem very common unless you're running mainframes.
Funnily enough, I've seen a lot more fixed point arithmetic in software rasterizers than anywhere else. FreeType, GDI, WPF, WARP (D3D11 reference rasterizer) all use it heavily.
- kccqzy 2y agoI have worked on firmware that has plenty of fixed point arithmetic. The firmware usually runs on processors without hardware floating point units. For example certain Tesla ECUs use 32-bit integers where they divide it into four bits of integer part and 28 bits of fractional part. So values are scaled by 2^28.
- phkahler 2y ago>> The firmware usually runs on processors without hardware floating point units. I'm working on control code one an ARM cortex-M4f. I wrote it all in fixed point because I don't trust an FPU to be faster, and I also like to have a 32bit accumulator instead of 24bit. I recently converted it all to floating point since we have the M4f part (f indicate FPU), and it's a little slower now. I did get to remove some limit checking since I can rely on the calculations being inside the limits but it's still a little slower than my fixed point implementation.
- sitkack 2y agoThe other great thing about going fixed point is that it doesn't expose you to device specific floating point bugs, making your embedded code way more portable and easier to test. 32b float on your embedded device doesn't necessary match your 32b float running on your dev machine.
- bobmcnamara 2y ago32b float can match your desktop. Really just takes a few compiler flags(like avoiding -funsafe-math), setting rounding modes, and not using the 80bit Intel mode(largely disused after 64bit transition).
- sitkack 2y agoI understand what you are saying ... You aren't guaranteed that your microcontrollers float is going to match your desktop. Microcontrollers are riddled with bugs, unless you need floats and fixedpoint is fast enough. My recommendation is still to use fixedpoint if application is high reliability. Esp if your code needs to be portable across arm, risc-v, etc.
- bobmcnamara 2y agoMany microcontrollers today, including ARM, RISC-V, and Xtensa have IEEE compliant FPUs or libms available. Same numeric format, same rounding, same result. Fixed point isn't bad at all, just often slower when a compliant FPU is available.
- Someone 2y ago> IEEE compliant FPUs or libms available. Same numeric format, same rounding, same result. IEEE only mandates results within ½ ULP (= best possible) for basic operations such as addition, subtraction, multiplication, division, and reciprocal. For many other ones such as trigonometric functions, exponential and logarithms, results can (and do) vary between conforming implementations. https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.h...: “The IEEE standard does not require transcendental functions to be exactly rounded because of the table maker's dilemma. To illustrate, suppose you are making a table of the exponential function to 4 places. Then exp(1.626) = 5.0835. Should this be rounded to 5.083 or 5.084? If exp(1.626) is computed more carefully, it becomes 5.08350. And then 5.083500. And then 5.0835000. Since exp is transcendental, this could go on arbitrarily long before distinguishing whether exp(1.626) is 5.083500...0ddd or 5.0834999...9ddd. Thus it is not practical to specify that the precision of transcendental functions be the same as if they were computed to infinite precision and then rounded. Another approach would be to specify transcendental functions algorithmically. But there does not appear to be a single algorithm that works well across all hardware architectures. Rational approximation, CORDIC,16 and large tables are three different techniques that are used for computing transcendentals on contemporary machines. Each is appropriate for a different class of hardware, and at present no single algorithm works acceptably over the wide range of current hardware.”
- gatane 2y agoAre there any good benchmarks for float vs fixed point, specially for ARM systems?
- EasyMark 2y agoThat would vary wildly with the ARM chip you are talking about. I would say figure out which ARM you’re interested in and go down the rabbit hole from there.
- evoke4908 2y agoJust look at the instruction set for your particular CPU. Every CPU is different, but in most architectures I've seen, floating point operations are 2-3 times slower for the same word size. Single float adds are usually 2 or 3 CPU cycles while single-word integer adds are usually 1 cycle. Again, this is extremely dependent on the particular CPU you have. Some architectures do have single-cycle FPU operations, but it's not very common in microcontrollers as far as I can tell.
- cpeterso 2y agoWhy did you decide to convert your code to floating point if your fixed point implementation was faster and already written?
- aatd86 2y agoWhat do they use? Not float I hope. Plus given that some currencies have different precisions... Don't tell me it's rounding errors over trillion monies?! :o)
- fluoridation 2y agoThe industry standard in finance is decimal floating point. C# for example has 'decimal', with 128 bits of precision. On occasion I've seen people who didn't know any better use floats. One time I had to fix errors of single satoshis in a customer's database because their developer used 1.0 to represent 1 BTC.
- Maxatar 2y agoAs I indicate in another post, I work in finance and I use binary floats. So do a lot of others who work in the industry. I sympathize with people who think that IEEE floating points are some weird or error prone representation and that fixed point arithmetic solves every problem, but in my professional experience that isn't true and systems that start by using fixed point arithmetic eventually end up making a half-assed error prone and slow version of floating point arithmetic as soon as they need to handle more sophisticated use cases like handling multiple currencies, doing calculations involving percentages such as interest rates, etc etc... The IEEE 754 floating point standard is a very well thought out standard that is suitable for representing money as-is. If you have requirements such as compliance/legal/regulatory needs that mandate a minimum precision, then you can either opt to use decimal floating point or use binary floating point where you adjust the decimal place up to whatever legally required precision you are required to handle. For example the common complaint about binary floating point is that $1.10 can't be represented exactly so you should instead use a fixed integer representation in terms of cents and represent it as 110. But if your requirement is to be able to represent values exactly to the penny, then you can simply do the same thing but using a floating point to represent cents and represent $1.10 as the floating point 110.0. The fixed integer representation conveys almost no benefit over the floating point representation, and once you need to work with and mix currencies that are significantly out of proportion to one another, you begin to really appreciate the nuances and work that went into IEEE 754 for taking into account a great deal of corner cases that a fixed integer representation will absolutely and spectacularly fail to handle.
- myst 2y agoEvery half-competent software engineer knows about fixed point arithmetic, my friend.
- phkahler 2y ago>> Every half-competent software engineer... You meant 8192/16384 right? I like q14.
- EGreg 2y agoSmart contracts on EVM and other blockchains all use fixed point, for the simple reason that all machines have to get exactly the same result.