473,385 Members | 1,553 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Conversion signed/unsigned

Hello,

I'm trying to check if only the lsb 8 bits of an integer are used.

bool Func(int x)
{
if ((x & 0xFFFFFF00) == 0)
{
return true;
}
else
{
return false;
}
}

This actually comes down to checking if an integer is in the range
[0,255]. Alternatively I could do:

bool Func(int x)
{
if (x >= 0 && x <= 255)
{
return true;
}
else
{
return false;
}
}

Since the first function only contains one conditional jump and the
second one contains two, the first one should be faster. Oddly enough
when doing some performance tests I found out that the first one (with
only one condition/jump) is doing worse than the second one (with two
conditions/jumps). I've looked at the MSIL to try to figure out why and
found out that the first function is actually translated as:

ldarg.0
conv.i8
ldc.i4 0xffffff00
conv.u8
and
ldc.i4.0
conv.i8
bne.un.s ...

This code contains a number of 'conv' instructions which are causing
the overhead. So I'm wondering which value should be used so that only
4 bytes are used and the 24 MSB are set to 1 while the others are 0?
0xffffff00 is seen as an unsigned value while I want it to be seen as a
signed one of 4 bytes. Any ideas?

TIA

Yves

Feb 26 '06 #1
6 5636
yves <yv*********@gmail.com> wrote:

<snip>
This code contains a number of 'conv' instructions which are causing
the overhead. So I'm wondering which value should be used so that only
4 bytes are used and the 24 MSB are set to 1 while the others are 0?
0xffffff00 is seen as an unsigned value while I want it to be seen as a
signed one of 4 bytes. Any ideas?


You claim it's the "conv" instruction which is causing the overhead.
Have you actually examined the optimised, JITted assembly code which is
produced? Looking at the IL in isolation isn't terrible useful.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 26 '06 #2
I replaced 0xFFFFFF00 with -256 which is its decimal equivalent when
using signed 32 bit integers. When I compile that code, all 'conv'
instructions are gone and the result actually runs faster as one would
have suspected.

So for some reason 0xFFFFFF00 gets compiled to:
ldc.i4 0xffffff00
conv.u8

while -256 gets compiled to:
ldc.i4 0xffffff00

One implication of using 0xFFFFFF00 is that all other 'parties' in the
equation need to be represented by 8 bytes as well, meaning that more
'conv' instructions will be inserted into the code. There is nothing
the JITter can do about them.

Doing some further testing I noticed that "int y = 0xFFFF0000;"
generates a conversion error from unsigned to signed ints. The error
gets only thrown if you use a hex value which is high enough to
'corrupt' the sign bit. So if your hex value is represented by less
than 32 bits (<= 0x7FFFFFFF) it's considered signed while if it uses
all 32 bits (> 0x7FFFFFFF) it's considered unsigned. I guess there is
some logic to it but I don't really see it.

Yves

Feb 26 '06 #3
Alternately,
bool Func(int x)
{
if ((x & 255) == x)
{
return true;
}
else
{
return false;
}
}

or even
bool Func(int x)
{
return ((x & 255) == x);
}
yves wrote:
Hello,

I'm trying to check if only the lsb 8 bits of an integer are used.

bool Func(int x)
{
if ((x & 0xFFFFFF00) == 0)
{
return true;
}
else
{
return false;
}
}

This actually comes down to checking if an integer is in the range
[0,255]. Alternatively I could do:

bool Func(int x)
{
if (x >= 0 && x <= 255)
{
return true;
}
else
{
return false;
}
}

Since the first function only contains one conditional jump and the
second one contains two, the first one should be faster. Oddly enough
when doing some performance tests I found out that the first one (with
only one condition/jump) is doing worse than the second one (with two
conditions/jumps). I've looked at the MSIL to try to figure out why
and found out that the first function is actually translated as:

ldarg.0
conv.i8
ldc.i4 0xffffff00
conv.u8
and
ldc.i4.0
conv.i8
bne.un.s ...

This code contains a number of 'conv' instructions which are causing
the overhead. So I'm wondering which value should be used so that only
4 bytes are used and the 24 MSB are set to 1 while the others are 0?
0xffffff00 is seen as an unsigned value while I want it to be seen as
a signed one of 4 bytes. Any ideas?

TIA

Yves


--
Truth,
James Curran [erstwhile-MVP]
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
Feb 27 '06 #4
yves <yv*********@gmail.com> wrote:
I replaced 0xFFFFFF00 with -256 which is its decimal equivalent when
using signed 32 bit integers. When I compile that code, all 'conv'
instructions are gone and the result actually runs faster as one would
have suspected.
But that doesn't mean it's the "conv" that's taking the time. I suspect
the time is really being taken by then performing a 64-bit "AND"
instead of a 32-bit one.
So for some reason 0xFFFFFF00 gets compiled to:
ldc.i4 0xffffff00
conv.u8

while -256 gets compiled to:
ldc.i4 0xffffff00

One implication of using 0xFFFFFF00 is that all other 'parties' in the
equation need to be represented by 8 bytes as well, meaning that more
'conv' instructions will be inserted into the code. There is nothing
the JITter can do about them.

Doing some further testing I noticed that "int y = 0xFFFF0000;"
generates a conversion error from unsigned to signed ints. The error
gets only thrown if you use a hex value which is high enough to
'corrupt' the sign bit. So if your hex value is represented by less
than 32 bits (<= 0x7FFFFFFF) it's considered signed while if it uses
all 32 bits (> 0x7FFFFFFF) it's considered unsigned. I guess there is
some logic to it but I don't really see it.


It should only generate that in a "checked" context. Try using:
int y = unchecked((int)0xffffff00);

and it should be fine.

If you change your original method to:

bool Func(int x)
{
if ((x & -0x100) == 0)
{
return true;
}
else
{
return false;
}
}

you'll find there's no 64-bit conversions going on.

The method is also a lot shorter in IL (as well as C#) if you change it
to:

bool Func(int x)
{
return ( (x & -0x100) == 0);
}

I haven't tested the JITted speed of that, but it's worth trying.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 27 '06 #5
yves wrote:
Hello,

I'm trying to check if only the lsb 8 bits of an integer are used.

bool Func(int x)
{
if ((x & 0xFFFFFF00) == 0)
{
return true;
}
else
{
return false;
}
}

This actually comes down to checking if an integer is in the range
[0,255]. Alternatively I could do:

bool Func(int x)
{
if (x >= 0 && x <= 255)
{
return true;
}
else
{
return false;
}
}


why don't you do:
bool Func(int x)
{
return ((uint)x <= 255);
}

?

FB

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Feb 27 '06 #6

"yves" <yv*********@gmail.com> wrote in message
news:11**********************@u72g2000cwu.googlegr oups.com...
| Hello,
|
| I'm trying to check if only the lsb 8 bits of an integer are used.
|
| bool Func(int x)
| {
| if ((x & 0xFFFFFF00) == 0)
| {
| return true;
| }
| else
| {
| return false;
| }
| }
|
| This actually comes down to checking if an integer is in the range
| [0,255]. Alternatively I could do:
|
| bool Func(int x)
| {
| if (x >= 0 && x <= 255)
| {
| return true;
| }
| else
| {
| return false;
| }
| }
|
| Since the first function only contains one conditional jump and the
| second one contains two, the first one should be faster. Oddly enough
| when doing some performance tests I found out that the first one (with
| only one condition/jump) is doing worse than the second one (with two
| conditions/jumps). I've looked at the MSIL to try to figure out why and
| found out that the first function is actually translated as:
|
| ldarg.0
| conv.i8
| ldc.i4 0xffffff00
| conv.u8
| and
| ldc.i4.0
| conv.i8
| bne.un.s ...
|
| This code contains a number of 'conv' instructions which are causing
| the overhead. So I'm wondering which value should be used so that only
| 4 bytes are used and the 24 MSB are set to 1 while the others are 0?
| 0xffffff00 is seen as an unsigned value while I want it to be seen as a
| signed one of 4 bytes. Any ideas?
|
| TIA
|
| Yves
|

Note that the IL doesn't reflect what's really done by the JIT, the JIT
compiler is platform dependent (X86/X64/IA), and knows exactly what it
should do depending on the underlying platform.
For instance the conv instructions are bogus, they aren't translated on X86.
What's really going on can be seen in X86 code generated by the JIT.
Both of the following should generate identical X86 code (like case2), but
it's not....

if ((x & 0xFFFFFF00) == 0)
if ((x & -256) == 0)

Case1
if ((x & 0xFFFFFF00) == 0)
native (JIT compile) code.
8bf1 mov esi,ecx
33ff xor edi,edi
8bc6 mov eax,esi
c1f81f sar eax,0x1f
f7c600ffffff test esi,0xffffff00
0f95c0 setne al
0fb6c0 movzx eax,al
85c0 test eax,eax
7505 jnz 00cb00e5
bf01000000 mov edi,0x1
8bc7 mov eax,edi
5e pop esi
5f pop edi
c3 ret

Here the value x is "sign tested", this is done by shifted to the right (sar
eax,31) through the CF flag, if x is <0 then CF=true else it's false, but
the CF is not tested further in the code, so this (mov and sar) is bogus,
while Case2....

if ((x & -256) == 0)

8bf1 mov esi,ecx
33ff xor edi,edi
f7c600ffffff test esi,0xffffff00
0f95c0 setne al
0fb6c0 movzx eax,al
85c0 test eax,eax
7505 jnz 00cb0120
bf01000000 mov edi,0x1
8bc7 mov eax,edi
5e pop esi
5f pop edi
c3 ret

is more efficient as the "sign test" is not done, why this is done? Well,
this is something you should ask the JIT team ;-)
Anyway, you see there is no conversion done and no 64 bit operations
performed (note that this is case on X64).

Willy.
Feb 27 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Ken Tough | last post by:
Seems like a simple thing to find out, but I'm struggling. I have googled, but everything I find is about implicit conversion, not explicit. Is this implementation-specific, or does ANSI/ISO...
16
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. ...
2
by: G Fernandes | last post by:
Hello, I have a question about using an unsigned int and a signed long int in an expression (where UINT_MAX > LINT_MAX). Based on the conversion rules, the unsigned int will be convered to...
7
by: CBFalconer | last post by:
Consider: #include <stdlib.h> /* An elementary optimizer is expected to remove most code */ /* Return the absolute value */ unsigned long ulabs(long j) { if (0 == LONG_MIN + LONG_MAX) { if...
14
by: junky_fellow | last post by:
Can anybody please explain this: When a value with integer type is converted to another integer type other than _Bool, if the new type is unsigned, the value is converted by repeatedly...
6
by: sarathy | last post by:
Hi, What is integer promotion? How is it different from arithmetic conversion? Regards, Sarathy
6
by: NM | last post by:
I am given an int and have to tell whether the bit representation of that int is a palindrome or not. Here is what I have come up with bool isIntPalindrome(int num) { unsigned int temp = num;...
9
by: Notebooker | last post by:
Hello, I'm an intermediate noob reading-in data from ascii-file using an ifstream object. I have specified a c-style string buffer with size of type size_t and I am specifying to use this...
7
by: somenath | last post by:
Hi All, I am trying to undestand "Type Conversions" from K&R book.I am not able to understand the bellow mentioned text "Conversion rules are more complicated when unsigned operands are...
5
by: Peng Yu | last post by:
Hi, Please see the following code and the output. It seems that if one of %'s oprand is unsigned, the other will also be converted to unsigned. There is a operator precedence table in...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.