flat assembler
Message board for the users of flat assembler.
Index
> Main > multiplying signed and unsigned integer 
Author 

bitRAKE
vivik wrote: But to multiply a signed and an unsigned integer, which should you use? Quote: Also, which kind of integer you use more often, signed or unsigned? Where do you use each? 

21 Apr 2017, 22:05 

revolution
vivik wrote: But to multiply a signed and an unsigned integer, which should you use? vivik wrote: Also, which kind of integer you use more often, signed or unsigned? 

21 Apr 2017, 23:46 

Furs
BTW you can use imul for unsigned multiplications unless you need the upper half.
The lower half (i.e. 32bit x 32bit > 32bit lower half result) are the same whether you use mul or imul. There's a difference only if you are interested in the upper half. 

22 Apr 2017, 11:16 

vivik
I'm confused by the result of division. Any idea what happened here?
MOV EAX,5 XOR EDX,EDX MOV ECX,2 ; eax fffffffb ; ecx fffffffe IDIV ECX ; eax 80000003 ;why? ; edx 1 MOV EAX,5 XOR EDX,EDX MOV ECX,2 ; eax fffffffb ; ecx fffffffe DIV ECX ; eax 0 ;why? ; edx fffffffb 

22 Apr 2017, 12:59 

revolution
IDIV:
EDX:EAX = 0x00000000fffffffb = +4294967291 ECX = 0xfffffffe = 2 Result = 0x80000003 = 2147483645 CPU is Correct DIV: EDX:EAX = 0x00000000fffffffb = +4294967291 ECX = 0xfffffffe = +4294967294 Result = 0x00000000 = 0 CPU is Correct Explanation: I suspect you want to use cdq instead of xor edx,edx. 

22 Apr 2017, 13:10 

vivik
Thanks!
Hope I don't annoy you too much. 

22 Apr 2017, 13:44 

vivik
Never seen an integer overflow before, didn't knew this exception existed.


22 Apr 2017, 14:13 

vivik
Question about big numbers.
I know it's possible to add or substract 64 96 or 128bit numbers on 32bit processor with the use of flags. But is it possible to multiply or divide them? This is probably a math question. After I learned that div can cause exception if you put something weird in edx, I probably never going to divide a 64bit number(, unless I know that it's safe). There was this link in the sticky http://www.x86asm.net/articles/workingwithbignumbersusingx86instructions/ , but it limits itself at 64bit numbers. 

23 Apr 2017, 10:12 

revolution
vivik wrote: I know it's possible to add or substract 64 96 or 128bit numbers on 32bit processor with the use of flags. But is it possible to multiply or divide them? You also can't directly multiply them. But a basic long multiply (like you learned in school) can be used. And for larger numbers things like Karatsuba and FFT can be a win. 

23 Apr 2017, 10:21 

Furs
For multiplying/division of large 64bit numbers on 32bit mode (or for dynamic range) you should try and use the x87 FPU with the 80bit precision if you can (unless you require even higher results). You can store any 64bit integer exactly in one 80bit FPU register and all operations can be done exact (in terms of 64bit integer results) as long as you require only 64bits of integer precision, and multiplying them is a matter of multiplying their significands (normal 64bit x 64bit multiply) and adding their exponents.
Make sure the FPU control word is set appropriately to use all 80bits of precision because some stupid OS like Windows sets it to 64bit only. (you can easily change it with asm) Obviously I don't think it will work without precision loss if you need a number larger than 64 bits in the result (unless they have a certain multiple of a powerof2 each, then you get extra precision bits due to increased dynamic range), but since it's floating point its dynamic range will be huge. 

25 Apr 2017, 18:21 

fasmnewbie
Furs wrote: For multiplying/division of large 64bit numbers on 32bit mode (or for dynamic range) you should try and use the x87 FPU with the 80bit precision if you can (unless you require even higher results). You can store any 64bit integer exactly in one 80bit FPU register and all operations can be done exact (in terms of 64bit integer results) as long as you require only 64bits of integer precision, and multiplying them is a matter of multiplying their significands (normal 64bit x 64bit multiply) and adding their exponents. No. F80 is good only for 18 significant digits. So representing max 0xffffffffffffffff (20 digits) with F80, will give you inexact result due to exponentiation. Secondly, FPU and the general registers use different kind of overflow exceptions and flags. What may seem to be overflow in integers, may look fine in SFLAG register of the FPU. Thirdly, signmess in FPU and general registers are interpreted quite differently. 0 and 0.0 may give you trouble. Next, FPU involves other kind of exceptions such as NaN (QNaN and SNaN) which is not relevant to integer operations but do affect the results and the entire operations. Finally, 80bit precision is only good as far as 63 mantissa bits. In contrast to integers (2^64  1). So either in 32bit or 64bit CPU, using FPU 80bit precisions to represent a 64 integer is not smart in any way. 

25 Apr 2017, 21:20 

Furs
fasmnewbie wrote: No. F80 is good only for 18 significant digits. So representing max 0xffffffffffffffff (20 digits) with F80, will give you inexact result due to exponentiation. fasmnewbie wrote: Secondly, FPU and the general registers use different kind of overflow exceptions and flags. What may seem to be overflow in integers, may look fine in SFLAG register of the FPU. fasmnewbie wrote: Thirdly, signmess in FPU and general registers are interpreted quite differently. 0 and 0.0 may give you trouble. 0.0 converted back to integer is 0, no issue at all. What trouble are you even speaking of. Multiplication by 0 is also 0 result (or 0, but again, when you convert it back when done, it's not an issue). fasmnewbie wrote: Next, FPU involves other kind of exceptions such as NaN (QNaN and SNaN) which is not relevant to integer operations but do affect the results and the entire operations. Obviously you can do weird floating point math and prove me wrong, but that's beside the point. You cannot do those with integer operations, so why even think about them? In these cases it's "wrong result" vs "impossible code" (with integers) so it's still better. fasmnewbie wrote: Finally, 80bit precision is only good as far as 63 mantissa bits. In contrast to integers (2^64  1). Think about it like this, people used to copy data with the FPU (using integer loads and stores, because otherwise NaNs would give you trouble if the data happened to have that pattern) 8 bytes at a time before SSE was mainstream. You understand this right? A data copy operation is not allowed to change even 1 bit and must preserve all 8 bytes perfectly. Again, with integer loads and stores, because otherwise the FPU could mess the number up in certain cases (NaNs) but with integers no issue at all, since the significand itself is 64 bits wide. That's why they weren't copying 10 bytes at a time. Most people think floating point math is unpredictable and random but that's nonsense. You can do all operations with integer precision at least as wide as the significand is with absolutely no precision loss whatsoever (obviously, if you are looking for an integer result and truncate the fraction) 

25 Apr 2017, 22:34 

fasmnewbie
Furs wrote:
Yeah genius. f dt 18446744073709551615.0 ;(max 64bit integer unsigned) fld [f] How do you think this may look like in the FPU register? 1.84467440737095516E+19 I wonder where the other 2 digits go... 

25 Apr 2017, 23:47 

revolution
fasmnewbie wrote: f dt 18446744073709551615.0 ;(max 64bit integer unsigned) 

26 Apr 2017, 03:13 

fasmnewbie
revolution wrote:
oh, ok then. I misread Furr's earlier comment. I thought he meant to use 80 bit precisions (DT) to represent an integer. 

26 Apr 2017, 09:19 

< Last Thread  Next Thread > 
Forum Rules:

Copyright © 19992020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.