flat assembler
Message board for the users of flat assembler.

Index > Main > Best way to calculate percentage?

Author
Thread Post new topic Reply to topic
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 Sad that's why I need best way to calculate it, thanks!
Post 26 Nov 2012, 14:30
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20453
Location: In your JS exploiting you and your system
revolution 26 Nov 2012, 14:35
Multiply first, then divide.

Additionally you can add a rounding stage if wanted/needed.


Last edited by revolution on 26 Nov 2012, 14:38; edited 1 time in total
Post 26 Nov 2012, 14:35
View user's profile Send private message Visit poster's website Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 26 Nov 2012, 14:37
damn you're right.. thank you!
Post 26 Nov 2012, 14:37
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
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.
Post 26 Nov 2012, 17:09
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20453
Location: In your JS exploiting you and your system
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.
Post 26 Nov 2012, 23:45
View user's profile Send private message Visit poster's website Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
AsmGuru62 27 Nov 2012, 13:33
Yes, it is possible, but FPU is so much more fun!
Integers are boring!
Post 27 Nov 2012, 13:33
View user's profile Send private message Send e-mail Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 27 Nov 2012, 15:46
Wow, didn't knew about that API Shocked
Post 27 Nov 2012, 15:46
View user's profile Send private message Reply with quote
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. Razz
Post 27 Nov 2012, 16:08
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
AsmGuru62 27 Nov 2012, 17:43
It does rounding, so you'll need more instructions than two and maybe a comparison.
Post 27 Nov 2012, 17:43
View user's profile Send private message Send e-mail Reply with quote
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
        add     eax, ebx    
Post 27 Nov 2012, 20:40
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
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)
Post 28 Nov 2012, 04:54
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
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%.
Post 28 Nov 2012, 15:34
View user's profile Send private message Send e-mail Reply with quote
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.
Post 28 Nov 2012, 15:42
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
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%.
Post 28 Nov 2012, 16:41
View user's profile Send private message Send e-mail Reply with quote
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
    
Post 28 Nov 2012, 17:02
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
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%.
Smile
Post 28 Nov 2012, 17:28
View user's profile Send private message Send e-mail Reply with quote
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.
Post 28 Nov 2012, 21:58
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1671
Location: Toronto, Canada
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.
Post 28 Nov 2012, 22:48
View user's profile Send private message Send e-mail Reply with quote
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. Razz
Post 28 Nov 2012, 23:24
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
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.
Post 29 Nov 2012, 12:23
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.