Multiplying by the inverse is not the same as the division

Multiplying by the inverse is not the same as the division

In school, we learn that the division is the same as multiplying the inverse (or reciprocal), that is x / y = x (1/y). In software, this does not work as-is when working with integers since 1/y is not an integer when y is an integer (except for y = 1 or y = -1). However, computers have floating-point numbers which are meant to emulate real numbers. It is reasonable to expect that x / y = x (1/y) will work out with floating-point numbers. It does not.

For example, dividing by 3.1416 and multiplying by 1/3.1416 do not result in the same numbers, when doing the computation on a computer.

To prove it, let me pull out my node (JavaScript) console…

> x = 651370000000
> x / 3.1416 * 3.1416
651370000000
> invd = 1 / 3.1416
> x * invd * 3.1416
651370000000.0001        

Maybe only JavaScript is broken? Let us try in Python…

>>> x = 651370000000
>>> x / 3.1416 * 3.1416
651370000000.0
>>> invd = 1 / 3.1416
>>> x * invd * 3.1416
651370000000.0001        

Always keep in mind that floating-point numbers are different from real numbers… for example, half of all floating-point numbers are in the interval [-1,1].

Antonio Mallia

Staff Research Scientist at Pinecone

9 小时前

The question is: “is one faster than the other one?” If so, why is that?

回复
Brian Budge

Senior Research Software Tech Lead/Manager at Reality Labs Research

16 小时前

This can be important at times, but it is still a valid optimization in a lot of cases. Beware that -ffast-math flag in some compilers will enable this reciprocal math transparently (by incorporating -freciprocal-math)

要查看或添加评论,请登录

Daniel Lemire的更多文章

  • Speeding up C++ code with template lambdas

    Speeding up C++ code with template lambdas

    Let us consider a simple C++ function which divides all values in a range of integers: A division between two integers…

  • An overview of parallel programming (Go edition)

    An overview of parallel programming (Go edition)

    In practice, the software we write runs on several processors. Unfortunately, much of what we take for granted on a…

  • How fast can you open 1000 files?

    How fast can you open 1000 files?

    Jarred Sumner, the main author of the Bun JavaScript engine, commented a few days ago on X that opening many files on…

    1 条评论
  • AVX-512 gotcha: avoid compressing words to memory with AMD Zen 4 processors

    AVX-512 gotcha: avoid compressing words to memory with AMD Zen 4 processors

    Convention computer instructions operate on a single piece of data at once (e.g.

    4 条评论
  • Thread-safe memory copy

    Thread-safe memory copy

    A common operation in software is the copy of a block of memory. In C/C++, we often call the function memcpy for this…

    2 条评论
  • Programmer time and the pitfalls of wasteful work

    Programmer time and the pitfalls of wasteful work

    Programmer time is precious. This realization should shape our approach to software development, focusing our efforts…

  • Regular expressions can blow up!

    Regular expressions can blow up!

    Regular expressions, often abbreviated as regex, are a powerful tool for pattern matching within text. For example, the…

    6 条评论
  • Checking whether an ARM NEON register is zero

    Checking whether an ARM NEON register is zero

    Your phone probably runs on 64-bit ARM processors. These processors are ubiquitous: they power the Nintendo Switch…

  • JavaScript hashing speed comparison: MD5 versus SHA-256

    JavaScript hashing speed comparison: MD5 versus SHA-256

    Hashing algorithms convert input data into a fixed-size string of characters, known as a hash value or digest. These…

  • Counting the digits of 64-bit integers

    Counting the digits of 64-bit integers

    Given an integer in software, you may want to know how many decimal digits it needs. For example, the integer 100…

    3 条评论