Solved

float computing algorithm and BCD operation

Posted on 2002-07-17
13
439 Views
Last Modified: 2011-10-03
Anyone know the float computing algorithm, and BCD operation? How should I do add/minus/multiply/divide operation with operands if I can't use the float/double data type.
0
Comment
Question by:99525
  • 9
  • 2
13 Comments
 
LVL 1

Expert Comment

by:acerola
Comment Utility
Floating point variables have three parts.

1-A bit to specify the sign.
2-digits
3-position of the point.

Like this:
0.25 = + 25 *10^-2
-123.456 = - 1233456 *10^-3
25000 = + 25000 *10^0

The first part stores the sign (+ or -). The second store the digits (25 or 123456 or 25000). The third stores the power of ten the number is multiplied by (-2 or -3 or 0)
0
 
LVL 1

Expert Comment

by:acerola
Comment Utility
Now the operations. Suppose you only have the data type for signed integer. So you can use two integer variables to store the result of a floating point operation. Something like this:

int digits,point

digits = 123450
point = 3
(that is number 123.456)

A fuction for division (the sintax is incorrect. but that is the idea):

fuction divide (int numerator,denominator) {

const maxprecision = 10;
int digits,point,i;

for (i=0,i<maxprecision,i++) {

  digits = (numerator*10^i) / denominator;
   
  if (digits*denominator = numerator*10^i) {
    /* exact division, no more decimal places */
    break; /* or the correct statement to exit the for loop*/
  }
}
point = i;

return digits,point; /*that is incorrect, you must use some kind of structure/record to output the two values*/
}

Got it?

lets check for numerator = 1 and denominator = 4 (0.25)

i = 0

digits = (numerator*10^i) / denominator;
digits = (1*1) / 4 = 0

if (digits*denominator = numerator*10^i) {
if (0*4=1*1) - false, loop continues

i = 1

digits = (1*10) / 4 = 3 (or 2, i dont know if the language rounds 2.5 to 2 or 3)
if ( (3*4) = 1*10 ) false
in the other case where the language makes 2.5 => 2
if ( (2*4) = 1*10 ) false anyway
loop continues

i = 2

digits = (1*100) / 4 = 25
if (25*4) = 1*100 (true, loop stops)
digits = 25
point = i = 2

so the answer is digits*10^-point = 0.25

if we have too many decimal places, the loop will stop at maxprecision.
0
 
LVL 1

Expert Comment

by:acerola
Comment Utility
for sum/subtraction you must put both numbers with the same point value and then sum/subtract normally.

I will use the structure:
number.digits
number.point
I don't know how to define it in C. It is probably using a record or someting.

function sumsubtract (structure number1, number2) {

structure result;

if (number1.point > number2.point) {

  number2.digits = number2.digits*10^(number1.point-number2.point);
  number2.point = number1.point;

} elseif (number1.point < number2.point) {

  number1.digits = number1.digits*10^(number2.point-number1.point);
  number1.point = number2.point;

}

result.point = number1.point /*or number2.point, they should be the same by now*/

result.digits = number1.digits-number2.digits;

return result;

}

Now the test. We want to subtract 1.25 - 0.5.

number1.digits = 125
number1.point = 2
nubber2.digits = 5
number2.point = 1

function runs

number1.point > number2.point

  number2.digits = number2.digits*10^(number1.point-number2.point);
  number2.digits = 5 * 10^(2-1) = 50
  number2.point = number1.point
  number2.point = 2

result.point = 2
result.digits = 125-50 = 75

so the answer is 0.75
0
 
LVL 1

Expert Comment

by:acerola
Comment Utility
finally for multiplication. just multiply the digits and sum the point.

result.point = number1.point + number2.point
result.digits = number1.digits * number2.digits

for example, 6.2 * 0.5.

result.digits = 62 * 5 = 310
result.point = 1 + 1 = 2

the answer is 310*10^-2 = 3.10 = 3.1
0
 
LVL 1

Expert Comment

by:acerola
Comment Utility
now a function to remove trailing zeroes, like the one on the multiplication:

while ( (result.digits/10)*10 = result.digits ) {

  result.digits = result.digits/10;
  result.point = result.point - 1;

}

testing:

result.digits = 25000
result.point = 4
(number 2.5000 = 2.5)

loop 1

(result.digits/10)*10 = result.digits
(25000/10)*10 = 2500*10 = 25000 (true)
result.digits = 2500
result.point = 3

loop 2

(result.digits/10)*10 = result.digits
(2500/10)*10 = 250*10 = 2500 (true)
result.digits = 250
result.point = 2

loop 3

(result.digits/10)*10 = result.digits
(250/10)*10 = 25*10 = 250 (true)
result.digits = 25
result.point = 1

loop 3

(result.digits/10)*10 = result.digits
(25/10)*10 = 2*10 = 20 (false)
(25/10)*10 = 3*10 = 30 (false anyway if the language rounds up)

loop stops

return:
result.digits = 25
result.point = 1

0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 1

Expert Comment

by:acerola
Comment Utility
sorry, the last loop should be loop 4. copy and paste should be smarter ;)
0
 
LVL 1

Expert Comment

by:acerola
Comment Utility
You can incorporate the number.point and number.digits into a single biginteger:

suppose you will only handle numbers bigger than 1*10^-99 (0 < point < 99):

biginteger = number.digits*100 + number.point;

the way back

number.digits = biginteger / 100;
number.point = biginteger - number.digits;

the number 1.25 would be stored as 12502 (125 02)
0
 

Author Comment

by:99525
Comment Utility
I may transplant these code to assembly finally. You know, the assembly may only has ADD/SUB instruction. So we'd better not use integer multiply or divide.
And if the integer data type is 4-bytes long, the max precision is only 10 digits. But the precision I need is far higher than 10 digits. So we can't depend on integer operations.

I have thought of float point variable like this:
sign    /* 1 byte */
point   /* 1 byte, power of 10 */
digits  /* 10 bytes, in BCD format */

Then I have 20-digits precision, and the range is 10^128.

But I don't know how to do BCD multiply and divide, and I also worry about the speed of BCD operation.
All operations in decimal system may save the time, I hope.
0
 
LVL 1

Expert Comment

by:acerola
Comment Utility
you can implement integer division/multiplication like this:

function multiply(int factor1,factor2) {

int i,result;

result = 0;

for (i=0;i<factor1;i++) {
  result = result + factor2;
}

return result;

}

function divide(int numerator,denominator) {

int i;

i = 0;

while (numerator >= denominator) {
i++;
numerator = numerator - denominator;
}

return i;

}
0
 

Author Comment

by:99525
Comment Utility
acerola,

The divide() will lose the remainder.
The algorithm is too slow.
0
 
LVL 1

Accepted Solution

by:
acerola earned 100 total points
Comment Utility
sorry, i used the same name for two different functions.

the last divide() function performs an integer division, the one that should be used inside the first divide() funciton.

the remainder can be calculated like this:

remainder = numerator-integer_divide(numerator,denominator)*denominator

the remainder of 3/2

remainder = 3-integer_divide(3,2)*2
remainder = 3-1*2 = 1

there may be faster ways to calculate that. i just used the definition of the multiplication and division operations. maybe the processor has a instruction to perform those?
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

How to Win a Jar of Candy Corn: A Scientific Approach! I love mathematics. If you love mathematics also, you may enjoy this tip on how to use math to win your own jar of candy corn and to impress your friends. As I said, I love math, but I gu…
Article by: Nicole
This is a research brief on the potential colonization of humans on Mars.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now