Link to home
Start Free TrialLog in
Avatar of marcy106
marcy106

asked on

multiplication and rounding numbers to nearest integer in assembly

how can i do this operation in asembly and rounding the number to nearest interger Ex:
 2 * 1.618 = 3.236 and rounded to 3?
ASKER CERTIFIED SOLUTION
Avatar of Dawaffleman
Dawaffleman

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of grg99
grg99

Ah, nice example, but I think the round-bit in the FPU only rounds at the LSBit, not by decimal 0.5 ??

im not sure exactly what you mean. are you saying that the FPU will only round the part left of the decimal point?
here is an excerpt from the AOA talking about the FPU control register:
-------------------------------------------------------------------------------------------
Bits 10 and 11 provide rounding control according to the following values:

Rounding Control Bits 10 & 11 Function
00 To nearest or even
01 Round down
10 Round up
11 Truncate

The "00" setting is the default. The 80x87 rounds values above one-half of the least significant bit up. It rounds values below one-half of the least significant bit down. If the value below the least significant bit is exactly one-half the least significant bit, the 80x87 rounds the value towards the value whose least significant bit is zero. For long strings of computations, this provides a reasonable, automatic, way to maintain maximum precision.

The round up and round down options are present for those computations where it is important to keep track of the accuracy during a computation. By setting the rounding control to round down and performing the operation, the repeating the operation with the rounding control set to round up, you can determine the minimum and maximum ranges between which the true result will fall.

-----------------------------------------------------------------------------------------------------------------
Hmm, I looked up FIST, and YOU're RIGHT!

It does round the real number according to the rounding settings of the FPU.


I've never seen this as every higher level language, like C, FORTRAN, Pascal that I've used has the convention of truncating reals when stored into integers.

So if you're unsure what the FPU rounding settings are, you'd better push the floating point status word, set the rounding option bits, do the math, then restore the FP status.



Regards,

grg99




The question is does the floating store to integer instruction round or truncate.  I always assumed it truncated.
oh yeah, before i whipped out the AOA to refresh my memory i was almost sure that it had truncated too, instead of rounding. i was suprised to see that it rounded by default. i was also happy because it made my code easier : )
Avatar of _Katka_
Hi, just notice for grg99 Delphi (object pascal)
has a function SetRoundMode which corresponds
to rounding control values (i.e. Nearest,Down,Up,Truncate)

regards,
Kate
Hi Dawaffleman,
> i would use the FPU, although im sure there are otherways to do it:

Sure, you can use fixed-point math, like in your case with three digits precision, meaning a factor of 1000:

2* 1.618
->
2000 * 1618 = 3236000
divide by 1000 -> 3226
Now, you can do truncate as:
3226 / 1000 = 3, 3*1000=3000

...or round to the nearest integer, that's simply by doing
(3226 + 500) / 1000 = 3, 3*1000 = 3000

I'm sure you can figure out the necessary ASM yourself.


Cheers!

Stefan
ok...im not quite sure what your getting at.

i also dont understand why you multiply 3*1000 at the end

???
Hi Dawaffleman or you can do it
in a complete floating-point manner.
Just like:

.model medium
.586
.stack 100h
.data

first dt 2.0
second dt 1.618
result dd  ?

.code

start:

finit
fld first
fld second
fmulp st(1),st(0)
fist value

end start

regards,
Kate
well much rather :)

.model medium
.586
.stack 100h
.data

first dd 2.0
second dd 1.618
result dd ?

.code

start:

finit
fld first
fld second
fmulp st(1),st(0)
fist result

end start

I hate typos,
Kate
oh i didnt know you could load floating point numbers into variable at the beginning like that, but duh me, why not heh, it makes sense.
Dawaffleman,
> i also dont understand why you multiply 3*1000 at the end

Because you use the last 3 integer digits as your fractional part, 3000 representing 3.000.

Unlike floating point math, fixed point is resistant to precision problems - you just have to check against overflows.

For example: You have a 10-digit (decimal) mantissa and want to do currency calculations, requiring at least two fractional digits. When you're using floating point math, values more than 10^8 won't have enough precision to fully support a two-digit fraction. You can get nasty and unnoticed precision problems (i.e., the cents don't add up like they should).

By using fixed-point math, an overflow is easily detected. That's why acient languages like COBOL are still popular, they have proper fixed-point support.
1618/1000 ?? What happened to (sqrt(5)+1)/ 2 ?
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.

I will leave the following recommendation for this question in the Cleanup topic area:
    Accept: Dawaffleman {http:#13465813}

Any objections should be posted here in the next 4 days. After that time, the question will be closed.

mbizup
EE Cleanup Volunteer