Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > signed vs. unsigned multiplication

Reply
Thread Tools

signed vs. unsigned multiplication

 
 
wrschlanger@gmail.com
Guest
Posts: n/a
 
      06-17-2012
Does anyone care to comment on the below program I wrote?
The question I was wondering is: why do compilers still use IMUL or MUL forsigned or unsigned multiplication respectively when there is no differencein the numeric value of the result provided the product size is the same as the size of the two factors that are being multiplied together?

This program prints PASS on my screen when I run it. Am I missing something?

Here is what I think is going on. The Intel manual lists IMUL for signed imultiplication and MUL for unsigned. It does this because originally those instructions always doubled capacity, i.e. the product had twice the size ofthe factors.

But then a variant of IMUL was introduced that discards the upper half of the result, i.e. it works like the C * operator. This is still listed as being for "signed" multiplication but it works equally well for unsigned multiplication and might be more efficient because it can take more operands.

Do any compiler writers know about this?? Or do they blindly trust the Intel manuals?

(By the way--interestingly I can't get (unsigned char)(0xff) to equal (signed char)(0xff) in GCC).
---
#include <cstdio>

int main()
{
for(int a = 0; a < 256; ++a)
{
for(int b = 0; b < 256; ++b)
{
signed char sa = a;
signed char sb = b;
unsigned char ua = a;
unsigned char ub = b;
signed char sc = sa * sb;
unsigned char uc = ua * ub;
unsigned char usc = sc;
if(uc != usc)
{
std:rintf("FAIL %02x * %02x = %02x vs. %02x\n", ua, ub, (unsigned int)(unsigned char)(sc), uc);
break;
}
}
}
std:rintf("PASS\n");
return 0;
}
 
Reply With Quote
 
 
 
 
Xavier Roche
Guest
Posts: n/a
 
      06-17-2012
Le 17/06/2012 16:31, http://www.velocityreviews.com/forums/(E-Mail Removed) a écrit :
> Does anyone care to comment on the below program I wrote?


There is no difference between signed/unsigned muls if you restrict them
to the source size AFAIK.

> The question I was wondering is: why do compilers still use IMUL or MUL for signed or unsigned multiplication respectively when there is no difference in the numeric value of the result provided the product size is the same as the size of the two factors that are being multiplied together?


extern unsigned char mulu(unsigned char a, unsigned char b) {
return a*b;
}

extern signed char muls(signed char a, signed char b) {
return a*b;
}

$ gcc -O -S -std=c99 sample.c -o sample.S

mulu:
movl %esi, %eax
imull %edi, %eax
ret

muls:
movl %esi, %eax
imull %edi, %eax
ret

 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      06-17-2012
On 6/17/2012 10:31 AM, (E-Mail Removed) wrote:
> Does anyone care to comment on the below program I wrote?


Comment: It's written in C++, not C. The two languages are
related but not identical, and differ in details large and small.
Try comp.lang.c++ for your C++ questions.

> (By the way--interestingly I can't get (unsigned char)(0xff) to equal (signed char)(0xff) in GCC).


This would be easy to explain in C, although I don't know whether
the C++ explanation would be similar. In C on a machine with eight-bit
characters, `signed char' cannot represent the value 0xFF=255 so the
conversion of 255 to `signed char' so "the result is implementation-
defined or an implementation-defined signal is raised." The usual
implementation-defined result is just to store as many bits as will fit,
which on a two's complement machine would produce -1. Meanwhile,
`unsigned char' *is* able to hold 255, so your interesting observation
is that 255 != -1; most people find this unsurprising.

--
Eric Sosman
(E-Mail Removed)d


 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      06-17-2012
(E-Mail Removed) writes:

> Does anyone care to comment on the below program I wrote?


First off, it's a C++ program and not a C one. I don't think there is a
significant area of difference in this program, but if you want answers
about C++ then comp.lang.c++ is a better place. It's possible that
follow-ups might stray into and area where the is an important
difference between the two languages.

> The question I was wondering is: why do compilers still use IMUL or
> MUL for signed or unsigned multiplication respectively when there is
> no difference in the numeric value of the result provided the product
> size is the same as the size of the two factors that are being
> multiplied together?


This is not really a C (or C++) question. You give a reasonable
explanation below, but from a C point of view I wonder why you care. Do
you think the compiler is getting something wrong as a result of the
choice being made?

> This program prints PASS on my screen when I run it. Am I missing
> something?


Since you ask, the answer must be yes. Presumably you expected
something else, but I can't be sure what. People here could offer more
help if you say why you think you might be missing something.

> Here is what I think is going on. The Intel manual lists IMUL for
> signed imultiplication and MUL for unsigned. It does this because
> originally those instructions always doubled capacity, i.e. the
> product had twice the size of the factors.
>
> But then a variant of IMUL was introduced that discards the upper half
> of the result, i.e. it works like the C * operator. This is still
> listed as being for "signed" multiplication but it works equally well
> for unsigned multiplication and might be more efficient because it can
> take more operands.
>
> Do any compiler writers know about this?? Or do they blindly trust the
> Intel manuals?


I would image that they trust the hardware documentation, but not
"blindly". I feel I'm not really getting at what is bothering you.

> (By the way--interestingly I can't get (unsigned char)(0xff) to equal
> (signed char)(0xff) in GCC).


Well, there's something wrong with your expectation here. Whilst
it's possible for these to be equal on some systems, it is not "normal"
for the systems that have gcc ported to them.

> #include <cstdio>


Change to stdio.h to make this a standard C header.

> int main()


In C, int main(void) is (marginally) better.

> {
> for(int a = 0; a < 256; ++a)
> {
> for(int b = 0; b < 256; ++b)
> {
> signed char sa = a;
> signed char sb = b;
> unsigned char ua = a;
> unsigned char ub = b;
> signed char sc = sa * sb;
> unsigned char uc = ua * ub;
> unsigned char usc = sc;
> if(uc != usc)
> {
> std:rintf("FAIL %02x * %02x = %02x vs. %02x\n", ua, ub, (unsigned int)(unsigned char)(sc), uc);
> break;
> }
> }
> }
> std:rintf("PASS\n");
> return 0;
> }


Turn std:rintf to plain printf to make this C.

--
Ben.
 
Reply With Quote
 
wrschlanger@gmail.com
Guest
Posts: n/a
 
      06-17-2012
Hi Ben,

I do a lot of low level stuff and regularly look at the output from my C compiler. (My apologies for posting C++ code to a C newsgroup).

I was basically wondering about Visual C++ whose code seemed (at least for the old version I checked) to always use MUL for 32-bit unsigned multiplication, and I was wondering whether or not my observation that IMUL would work just as well, was accurate.

This was answered by an earlier post, though I don't have a proof, I guess I don't need one as long as there's a general consensus -- and the fact that GCC generates identical code (using IMUL) is enough proof for me.

The reason I made the post was because I was unaware that GCC did this.

On Sunday, June 17, 2012 8:37:37 AM UTC-7, Ben Bacarisse wrote:
[snip]
> Turn std:rintf to plain printf to make this C.
>
> --
> Ben.


Thanks for the tips on converting to C. If I have any other questions I will use a C++ newsgroup, or make sure everything works with plain C. Actuallythis question would have been better suited for an assembly group since it's specific to x86, but then they might complain I used C and not assembly


Willow
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      06-17-2012


<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

> I was basically wondering about Visual C++ whose code seemed (at least for
> the old version I checked) to always use MUL for 32-bit unsigned
> multiplication, and I was wondering whether or not my observation that
> IMUL would work just as well, was accurate.
>
> This was answered by an earlier post, though I don't have a proof, I guess
> I don't need one as long as there's a general consensus -- and the fact
> that GCC generates identical code (using IMUL) is enough proof for me.


I'm doing some code generation at the moment and using MUL and IMUL. If the
latter works just as well, and could be faster because of the 32-bit, rather
than 64-bit, result, then I will use it.

Although the brief test I've just done shows no difference (not on my
processor anyway).

As for proof, testing that I get the same results on a selected range of
values will do me. It's not necessary to test all 2**64 possible pairs of
operands (and which would anyway take too long). And I wouldn't rely on the
output of GCC; there could be many reasons why the generated code is what it
is.

--
Bartc

 
Reply With Quote
 
Heikki Kallasjoki
Guest
Posts: n/a
 
      06-17-2012
On 2012-06-17, BartC <(E-Mail Removed)> wrote:
><(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>
>> I was basically wondering about Visual C++ whose code seemed (at least for
>> the old version I checked) to always use MUL for 32-bit unsigned
>> multiplication, and I was wondering whether or not my observation that
>> IMUL would work just as well, was accurate.
>>
>> This was answered by an earlier post, though I don't have a proof, I guess
>> I don't need one as long as there's a general consensus -- and the fact
>> that GCC generates identical code (using IMUL) is enough proof for me.

>

....
> operands (and which would anyway take too long). And I wouldn't rely on the
> output of GCC; there could be many reasons why the generated code is what it
> is.


The (maligned) Intel manual[1] is actually reasonably clear about this,
if you don't mind trusting it "blindly" for this occasion:

"The two- and three-operand forms may also be used with unsigned
operands because the lower half of the product is the same regardless if
the operands are signed or unsigned. The CF and OF flags, however,
cannot be used to determine if the upper half of the result is
non-zero."

(When using the "correct" version of MUL/IMUL, the CF or OF flag -- they
have the same value -- can be tested to see if any significant bits will
be lost when truncating the result back to 32 bits, in case this is of
interest.)


[1] Intel(R) 64 and IA-32 Architectures Software Developer's Manual,
Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z: "IMUL--Signed
Multiply", Vol. 2A, pp. 3-495.


--
Heikki Kallasjoki
 
Reply With Quote
 
Joe.
Guest
Posts: n/a
 
      06-25-2012

"Ben Bacarisse" <(E-Mail Removed)> wrote in message
news:0.2e4336d1fc519c6636b2.20120617163737BST.87r4 (E-Mail Removed)...
> (E-Mail Removed) writes:
>
>> Does anyone care to comment on the below program I wrote?

>
> First off, it's a C++ program and not a C one.


But you experience has no value.?

It's not about programming anymore, it's about who you programmed for. ?

I ask the hard questions. I should just shut up and capitalize on them?

Did Jesus die for anyone's sins?


 
Reply With Quote
 
Joe.
Guest
Posts: n/a
 
      06-25-2012

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
Hi Ben,

"I do a lot of low level stuff and regularly look at the output from my C
compiler. (My apologies for posting C++ code to a C newsgroup)."

But you don't want one of "dem jobs" either, huh? Did "your country" fail
you?




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
Source of term "multiplication" in matrix multiplication William Hughes C Programming 13 03-15-2010 02:04 PM
signed multiplication priya VHDL 2 11-17-2006 08:04 AM
Help to get a copy of A. D. Booth, "A signed binary multiplication technique," Weng Tianxiang VHDL 4 04-07-2005 04:10 PM
32x32 and 64x64 signed integer multiplication Christopher Dyken C Programming 18 02-24-2004 09:05 AM



Advertisments