Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 634
  • Last Modified:

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?
0
marcy106
Asked:
marcy106
  • 5
  • 3
  • 2
  • +3
1 Solution
 
DawafflemanCommented:
i would use the FPU, although im sure there are otherways to do it:

.model medium
.586                    ;pentium instructions
.stack 100h
.data

thosand dd 1000   ;needs to be 32 bit
two       dd 2        ;32 bit
value    dd  ?        ;doesnt need to be 32 bit, but what the heck


.code

start:

finit                   ;initiate FPU

fild 1618             ;this will load 1618 onto the fpu stack
fdiv thousand            ;divides 1618 by 1000 to get 1.618 on the stack
fild two                  ;load 2 onto the fpu stack
fmulp st(1),st(0)    ;multiply stack value and pop stack (0):   stack (1)=stack (1) * stack (0)
fist value             ;store value on top of stack to value, using fpu control flags (which are 'round'
                          ;                                                                                      at default)


end start


there i think that is what your looking for. try it out and see if it works
0
 
grg99Commented:
Ah, nice example, but I think the round-bit in the FPU only rounds at the LSBit, not by decimal 0.5 ??

0
 
DawafflemanCommented:
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.

-----------------------------------------------------------------------------------------------------------------
0
[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

 
grg99Commented:
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.
0
 
DawafflemanCommented:
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 : )
0
 
_Katka_Commented:
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
0
 
stefan73Commented:
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
0
 
DawafflemanCommented:
ok...im not quite sure what your getting at.

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

???
0
 
_Katka_Commented:
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
0
 
_Katka_Commented:
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
0
 
DawafflemanCommented:
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.
0
 
stefan73Commented:
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.
0
 
aib_42Commented:
1618/1000 ?? What happened to (sqrt(5)+1)/ 2 ?
0
 
mbizupCommented:
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
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

  • 5
  • 3
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now