flat assembler
Message board for the users of flat assembler.

 Index > Main > Best way to calculate percentage?
Author
Overflowz

Joined: 03 Sep 2010
Posts: 1046
Overflowz 26 Nov 2012, 14:30
Hi, I'm stuck calculating percentages. What is the best way to do it? I think using FPU instructions is much better than CPU.

Code:
```proc getpercentage, number, percentage
mov eax,[number]
mov ecx,[percentage]
xor edx,edx
div ecx
mov ecx,20 ;20%
imul eax,ecx
ret
endp    ```

if I pass first argument less than percentage, it's always zero that's why I need best way to calculate it, thanks!
26 Nov 2012, 14:30
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 20139
revolution 26 Nov 2012, 14:35
Multiply first, then divide.

Last edited by revolution on 26 Nov 2012, 14:38; edited 1 time in total
26 Nov 2012, 14:35
Overflowz

Joined: 03 Sep 2010
Posts: 1046
Overflowz 26 Nov 2012, 14:37
damn you're right.. thank you!
26 Nov 2012, 14:37
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 26 Nov 2012, 17:09
Win32 has an API called MulDiv() -- very handy for this. It does the rounding too. But for percentage points, like 27.093% - you need FPU.
26 Nov 2012, 17:09
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 20139
revolution 26 Nov 2012, 23:45
AsmGuru62 wrote:
But for percentage points, like 27.093% - you need FPU.
You can still use integers here also. Multiply by 100000 instead of 100 and print the decimal point in the proper position for display.
26 Nov 2012, 23:45
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 27 Nov 2012, 13:33
Yes, it is possible, but FPU is so much more fun!
Integers are boring!
27 Nov 2012, 13:33
Overflowz

Joined: 03 Sep 2010
Posts: 1046
Overflowz 27 Nov 2012, 15:46
Wow, didn't knew about that API
27 Nov 2012, 15:46
JohnFound

Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 27 Nov 2012, 16:08
To call OS API for operation that needs 2 instructions is a serious step towards hell.
27 Nov 2012, 16:08
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 27 Nov 2012, 17:43
It does rounding, so you'll need more instructions than two and maybe a comparison.
27 Nov 2012, 17:43
JohnFound

Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 27 Nov 2012, 20:40
Well, 7 actually (14 bytes).
Still not enough to use API call.
Code:
```; 14 bytes
; eax - signed multiplier 1
; ebx - signed multiplier 2
; ecx - signed divider
;
; the result is in eax
; the result without rounding is in ebx

imul    ebx
idiv    ecx
mov     ebx, eax
lea     eax, [edx*2]
cdq
idiv    ecx
27 Nov 2012, 20:40
Goplat

Joined: 15 Sep 2006
Posts: 181
Goplat 28 Nov 2012, 04:54
If it's a percentage of some task in progress to completion, the convention is to round down anyway (it's frustrating to see "100% done" when the task is not really done)
28 Nov 2012, 04:54
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 28 Nov 2012, 15:34
So, for how many seconds you see 100% done?
Like 2 secs? Or less?

In my opinion - this is a task for a progress bar control.
It supposed to have a value identifying the FULL process and
show 100% only if that value is reached.

Example: I need to copy 2,689,373,667 bytes (few files I selected)
When process goes - the copying thread sends messages to a control with a value how many bytes are copied as of now.

1. The control calculates percentage the usual way

2. If percentage is 100 (this may happen when 2,689,373,000 are copied) then control re-verifies that 100 using another way - comparing to a final value and if not same - shows 99%.
28 Nov 2012, 15:34
JohnFound

Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 28 Nov 2012, 15:42
Well, in your example and rounding arithmetically, 100% will be displayer while 13,446,868 bytes remains to be processed. How long this 100% will stay on the display depends on the work speed. In some cases it can be really long, especially if the transfer speed is not constant.
So, Goplat is right here - on progress calculations "trunc" type rounding should be used.
28 Nov 2012, 15:42
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 28 Nov 2012, 16:41
JohnFound: did you miss #2? (that sounds funny... Mike Myers kind of funny)
100% will not be displayed until value is reached maximum.
So, for last 13,446,867 bytes it will show 99%.
28 Nov 2012, 16:41
JohnFound

Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 28 Nov 2012, 17:02
AsmGuru62, I didn't miss 2. but it sounds really weird:

1. Calculate the percentage using incorrect for this context, more complex and slower algorithm.
2. Use some dirty hack (and more code) to circumvent the problems of p.1

Isn't it cleaner simply to round the percentage down???

Code:
```; pseudo code
imul [.percent]
idiv 100
```
28 Nov 2012, 17:02
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 28 Nov 2012, 17:28
yes - it is simpler, but then when it show 87% -- it may be actually 87.9999 - which is 88%.
28 Nov 2012, 17:28
Goplat

Joined: 15 Sep 2006
Posts: 181
Goplat 28 Nov 2012, 21:58
AsmGuru: your proposed scheme would display anything in the (98.5%,100%) range as 99%, which means 99% is displayed for 1.5x longer than other percentages. That's inconsistent, and also potentially annoying - progress appears to have gotten "stuck" at 99%.

If you just round down, then each percentage from 0% to 99% is displayed for the same proportion of progress. So it never gets "stuck" at any percentage as long as the progress measurement is accurate.
28 Nov 2012, 21:58
AsmGuru62

Joined: 28 Jan 2004
Posts: 1588
AsmGuru62 28 Nov 2012, 22:48
Programs can be annoying, but must function properly.
In this case my code will function properly in 98 cases out of 100.
Also, annoying is relative term - some users may not notice the inconsistency.
28 Nov 2012, 22:48
JohnFound

Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 28 Nov 2012, 23:24
AsmGuru62, if this 0.5% is important for you, you simply have to use one more digit and display 0.1% units (using the same "wrong" technique with rounding down). This way you will have small, compact and fast code. And no hacks at all.
28 Nov 2012, 23:24
typedef

Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 29 Nov 2012, 12:23
I think it'd be better to let the code/thread enable the "Continue / Finish" button after actually finishing the job and not after the percentage hits 100. Because like AsmGuru pointed out, you may have 100% when actually it's 99.999%. If the thread terminated, some files would not be copied. Then things like file corruption would come up.
29 Nov 2012, 12:23
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum