fresh
fresh

Reputation: 41

How to display 11.1 after div in assembly?

How to display 11.1 after the div? E.g 32/5=6.4, I am only able to display 6 so how to display 6.4?

OUT23:

    MOV BL,CNT  ;CNT is the total number of even number
    DIV BL
    MOV DL,AL
    MOV BH,AL
    MOV AH,09H
    LEA DX,MSG23
    INT 21H
    MOV DL,BH   ;print out the average, only the integer part able to display
    MOV AH,02
    ADD DL,30H
    INT 21H

Upvotes: 4

Views: 2347

Answers (3)

phuclv
phuclv

Reputation: 41932

If you want to divide two integers and print the fractional result then you can do it like when you divide by hand in elementary school. The initial division will give you the integer part of the result, then just repeatedly multiply the remainder part by 10 and divide by the divisor until it's zero or you have reached the intended precision to get the fraction

Take the example 32/5 above

  • Integer part:

    32/5 = 6 → Print out "6."
    
  • Fractional part:

    Remainder: 2, multiply it by 10 → 2*10 = 20
    20/5 = 4 → Print out "4"
    Remainder: 0, stop here
    

More complex divisions can also be done like above, just multiply the remainder by 10 after each step. If the result is infinite then stop when you get enough precision. For example: 25/11 = 2.27272727...

  25/11 = 2 R 3 → 2.
3*10/11 = 2 R 8 → 2
8*10/11 = 7 R 3 → 7
3*10/11 = 2 R 8 → 2
8*10/11 = 7 R 3 → 7
and so on...

Of course it can be done even faster by multiplying 10N to get N fractional digits at once


Alternatively use floating-point values and do a floating-point division with FDIV like others said. After that there are numerous ways to convert the float result into string, but it'll be exceedingly difficult to get a correctly rounded result, so it's better to just use libraries made for that purpose.

However for a very simple demonstration then again the above method can also be used:

  • Split the integer part of the result and print it followed by .
  • Multiply the integer part by 10, the integer part will be the next fractional digit
  • Remove the the integer part and repeat the above step until you reach the desired precision

A rough example is like this, disregarding errors due to binary floating-point properties

11.157
Int part: 11    → print 11.
Fractional part:
0.157*10 = 1.57 → print 1
 0.57*10 = 5.7  → print 5
  0.7*10 = 7    → print 7

More detailed information can be found in Turn float into string

Upvotes: 3

Chris Taylor
Chris Taylor

Reputation: 53709

As already stated DIV performs an integer division. Since it is an integer division, the resulting quotient and remainder are available in separate register pairs, the exact registers depends on the size of the divisor.

1 Byte Divisor

AX - Dividend
AH - Remainder
AL - Quotient

2 Byte Divisor

DX:AX - Dividend
DX - Remainder
AX - Quotient

4 Byte Divisor

EDX:EAX - Dividend
EDX - Remainder
EAX - Quotient

Since you are using a 1 byte divisor 'BL' the remainder will be in the AH register. In your case of 32/5 the AL register will contain the value 6 and the AH register the value 2 which means there is a remainder of 2/5 which is 0.4 giving you your answer of 6.4.

If you decide you use FPU operations you will need to load the two values 32 and 5 onto the FPU stack using the FLD instruction, once for each value, after which you call FDIV which will pop the two values off the FPU stack, divide them and push the result onto the FPU stack.

The result can then be move off the stack to a memory address using the FSTP instruction. Once you have the result you will need to convert that from the binary IEEE floating-point representation to a string representation which can be displayed on the screen.

Upvotes: 2

Paul R
Paul R

Reputation: 213060

DIV is an integer divide instruction. If you want floating point division then you'll need to look at FDIV.

Upvotes: 2

Related Questions