0

I have a simple problem, but because this "programming language" I am using is 32-bit and only supports basic functions such as addition, subtraction, multiplication, division, and concatenation (literally that's it), I am having some trouble.

For the input, I have a 16 digit number like so: 3334,5678,9523,4567

I want to then subtract 2 other random 16 digit numbers from this number and check if the first and last digits are 1.

For example, if the two other numbers are 1111,1111,1111,1111 and 1234,5678,9123,4565.
My final number would be: 0988,8888,9288,8891.

Here, the last number is 1, but the first number is 0, so the test would fail.

The issue is with 32-bit systems, there are massive errors due to not enough precision provided by the bits. What are some ways to bypass this issue?

7
  • If all you're doing is adding and subtracting, write your own decimal operations, place by place, using string handling. The only part that takes a bit of thought is handling carrying digits to the next place. Multiplication is almost as simple, but true FP division would take work. May 26, 2020 at 0:33
  • 1
    Represent the 16-digit decimal numbers as BCD (binary-coded decimal) strings. The precision (i.e. number of digits) is then unlimited. Some processors even have machine instructions that facilitate BCD arithemtic.
    – sawdust
    May 26, 2020 at 1:23
  • Have you tried 1111,1111,1111,1111.0+1234,5678,9123,4565.0 ? Most likely the floating-point numbers will have enough precision. May 26, 2020 at 2:14
  • 2
    You don't mention the language. For many languages, there exist "bignum" [en.wikipedia.org/wiki/Bignum] libraries that don't care what the CPU's precision or word size is. The cost is usually speed, but unless you're performing the operation you describe a billion times a second, you're probably fine. May 26, 2020 at 2:52
  • 3
    It's difficult to give suggestions without knowing all details about the language, but the standard way all languages deal with limited precision is to use multiple machine words. If your addition and subtraction has any kind of carry mechanism (you didn't tell us), or if you have operations that can be used to find out if there is a carry, that's the simplest approach.
    – dirkt
    May 26, 2020 at 4:07

1 Answer 1

2

For the input, I have a 16 digit number like so: 3334,5678,9523,4567

That is a 16-digit decimal number.

What are some ways to bypass this issue?
... Its [sic] a really unique problem

This is not a new or "unique" problem, and is typically solved with either BCD or multi-word integers.
Floating point, which emphasizes a wide range of magnitude over precision is typically inadequate for a solution, since (binary) double-precision claim up to 16 (decimal) significant digits but is not accurate for decimal fractions (i.e. 1/10 is a infinite binary fraction just like 1/3; see this article).

BCD (binary-coded decimal) strings allow unlimited precision (i.e. number of digits).
Some processors even have machine instructions that facilitate BCD arithemtic.
For financial applications there have been decimal (not binary) computers that used BCD arithmetic.

A binary computer with a word size of N bits is not constrained to arithmetic of integers of N bits.
The carry and borrow flags of the ALU facilitate arithmetic operations of multiple words.
See this answer to "Reason to use the carry bit and the overflow bit".

A computation-intensive program would probably prefer a multi-word integer or fixed-point solution for a speed advantage.
An input/output-intensive program (e.g. a calculator) would probably prefer a BCD integer or fixed-point solution for a conversion advantage. Four-function hand calculators typically use BCD (rather than binary) arithmetic.



Addendum

The two schemes mentioned above can be combined into a hybrid scheme.
Using 32-bit integers a binary-coded billion could be used instead of (unpacked) bytes and a binary-coded decimal.

Instead of using bytes to store an unpacked value between 0 and 9 (inclusive), expand the concept of BCD to use 32-bit integers that store a value between 0 and 999,999,999 (inclusive).

To represent a 16-digit decimal number, two 32-bit binary-coded billion words would be required.
This storage requirement is the same as if a 64-bit integer was used.
Conversion between binary and decimal radix is faster than pure-binary multiple words, while arithmetic is faster than BCD.
This hybrid scheme inherits the advantages of its origins.

2
  • Thanks sawdust. My background isnt really in computing science. I read some materials on BCD just now and will give it a shot. Thanks for the help.
    – Rui Nian
    May 26, 2020 at 5:19
  • @RuiNian -- Updated answer.
    – sawdust
    May 28, 2020 at 8:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .