473,320 Members | 1,910 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,320 software developers and data experts.

Subtracting unsigned entities

If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?

If x is smaller than y, then x-y is negative.

A naive approach is
if ( x y ) {
...
}

but a compiler may code (x>y) as (x-y 0).

--
Fred Kleinschmidt
Boeing Aero C&S
Jun 27 '08 #1
11 5652
fr*****************@boeing.com said:
If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?

If x is smaller than y, then x-y is negative.

A naive approach is
if ( x y ) {
...
}
Why is that naive?
>
but a compiler may code (x>y) as (x-y 0).
No, it can't do that if it won't produce the correct result.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #2
fr*****************@boeing.com writes:
If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?

If x is smaller than y, then x-y is negative.
Mathematically, yes. But in C, the difference of two values of
type unsigned int is always nonnegative.
A naive approach is
if ( x y ) {
...
}

but a compiler may code (x>y) as (x-y 0).
No, the compiler is obliged to produce the correct result.
--
"The way I see it, an intelligent person who disagrees with me is
probably the most important person I'll interact with on any given
day."
--Billy Chambless
Jun 27 '08 #3
On May 12, 11:18*pm, fred.l.kleinschm...@boeing.com wrote:
If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?

Let's take an example:

unsigned x, y;

x = 65530u;
y = 655u;

The difference between these two is 64875.

If you do (x-y), you'll get 64875u. However if you do (y-x), you'll
get an implementation-defined value which depends on the value of
UINT_MAX (because when you go past zero you'll start counting backward
from UINT_MAX).

If x is smaller than y, then x-y is negative.

A naive approach is
* *if ( x y ) {
* * * ...
* *}

but a compiler may code (x>y) as *(x-y 0)

The if method is the only one that comes to mind.
Jun 27 '08 #4
On May 12, 11:18*pm, fred.l.kleinschm...@boeing.com wrote:
If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?

If x is smaller than y, then x-y is negative.

A naive approach is
* *if ( x y ) {
* * * ...
* *}

but a compiler may code (x>y) as *(x-y 0).
What do you mean by difference?

If you mean x-y, then this will give strange results when x<y (it
can't be negative).

If you mean max(x,y)-min(x,y) then your 'naive' approach will likely
work well.

--
Bartc
Jun 27 '08 #5
Bart wrote:
fred.l.kleinschm...@boeing.com wrote:
If one knows that x and y are unsigned integers (of unknown
size - they may be short, int, long, long long), what is the
most portable way to determine their difference?
Subtraction. Though that need not be the minimum 'distance'
metric.
If x is smaller than y, then x-y is negative.

A naive approach is
if ( x y ) {
...
}

but a compiler may code (x>y) as (x-y 0).

What do you mean by difference?

If you mean x-y, then this will give strange results when x<y (it
can't be negative).
It can in some circumstances, e.g. USHRT_MAX < INT_MAX.

--
Peter
Jun 27 '08 #6
fr*****************@boeing.com wrote:
If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?

If x is smaller than y, then x-y is negative.

A naive approach is
if ( x y ) {
...
}

but a compiler may code (x>y) as (x-y 0).
It might code it as `x + 17`, too, but if it wants to be correct
both decisions would be suspect.

--
"Why, /yes/, madame. Certainly. Now?" - Lois McMaster Bujold /A Civil Campaign/

Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England

Jun 27 '08 #7
On May 12, 3:58*pm, Bart <b...@freeuk.comwrote:
On May 12, 11:18*pm, fred.l.kleinschm...@boeing.com wrote:
If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?
If x is smaller than y, then x-y is negative.
A naive approach is
* *if ( x y ) {
* * * ...
* *}
but a compiler may code (x>y) as *(x-y 0).

What do you mean by difference?

If you mean x-y, then this will give strange results when x<y (it
can't be negative).

If you mean max(x,y)-min(x,y) then your 'naive' approach will likely
work well.
The problem came up on a Unix platform, where some code was trying
to check for a double-click. Each time button1 is clicked, it checks
the time with the previous time it was clicked; if the difference is
small enough, a double-click is assumed.

The times are stored in a variable of type Time, defined as
an unsigned int on some platforms, unsigned long on others, storing
clock time in milliseconds.

For an unsigned int, the value will wrap every 47 days. The original
code was

if ( (newtime - oldtime) < doubleclicktime ) {
/* perform double-click action */
}

That code is unsafe: as oldtime approaches UINT_MAX, the risk
is that newtime might occur after time wraps, thus might be
a small integer, and (newtime - oldtime) is mathematically
negative.

Since others have said that the compiler is obliged to
perform the if-test properly, my solution is

if ( t2 t1 ) {
delta = t2 - t1;
}
else {
delta = (UINT_MAX - t1) + t2 + 1;
}

--
Fred Kleinschmidt

Jun 27 '08 #8
fr*****************@boeing.com wrote:
On May 12, 3:58 pm, Bart <b...@freeuk.comwrote:
>On May 12, 11:18 pm, fred.l.kleinschm...@boeing.com wrote:
>>If one knows that x and y are unsigned integers (of unknown size -
they may be short, int, long, long long), what is the most portable
way to determine their difference?
If x is smaller than y, then x-y is negative.
A naive approach is
if ( x y ) {
...
}
but a compiler may code (x>y) as (x-y 0).
What do you mean by difference?

If you mean x-y, then this will give strange results when x<y (it
can't be negative).

If you mean max(x,y)-min(x,y) then your 'naive' approach will likely
work well.

The problem came up on a Unix platform, where some code was trying
to check for a double-click. Each time button1 is clicked, it checks
the time with the previous time it was clicked; if the difference is
small enough, a double-click is assumed.

The times are stored in a variable of type Time, defined as
an unsigned int on some platforms, unsigned long on others, storing
clock time in milliseconds.

For an unsigned int, the value will wrap every 47 days. The original
code was

if ( (newtime - oldtime) < doubleclicktime ) {
/* perform double-click action */
}

That code is unsafe: as oldtime approaches UINT_MAX, the risk
is that newtime might occur after time wraps, thus might be
a small integer, and (newtime - oldtime) is mathematically
negative.
Doesn't matter. You've said the times are either
`unsigned int' or `unsigned long' depending on the platform,
and neither of these is subject to promotion. Hence, the
arithmetic will be carried out according to the unsigned
rules, and `tiny - huge' will yield `moderate', as desired.
Since others have said that the compiler is obliged to
perform the if-test properly, my solution is

if ( t2 t1 ) {
delta = t2 - t1;
}
else {
delta = (UINT_MAX - t1) + t2 + 1;
}
The `else' clause is just an obfuscated version of
the `then' clause, producing the same result.

--
Er*********@sun.com

Jun 27 '08 #9
fr*****************@boeing.com wrote:
Since others have said that the compiler is obliged to
perform the if-test properly, my solution is

if ( t2 t1 ) {
delta = t2 - t1;
}
else {
delta = (UINT_MAX - t1) + t2 + 1;
}
Not
if (t2 t1) delta = t2 - t1;
else delta = t1 - t2;

? Because that seems simpler and at least as correct.

(Of course I'd write it as

delta = t2 t1 ? t2 - t1 : t1 - t2;

)

--
/Questions? Answers! Answers? Questions!/ - Focus

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN

Jun 27 '08 #10
fr*****************@boeing.com writes:
On May 12, 3:58*pm, Bart <b...@freeuk.comwrote:
[ snip ]
For an unsigned int, the value will wrap every 47 days. The original
code was

if ( (newtime - oldtime) < doubleclicktime ) {
/* perform double-click action */
}

That code is unsafe:
No.
as oldtime approaches UINT_MAX, the risk
is that newtime might occur after time wraps, thus might be
a small integer,
Yes.
and (newtime - oldtime) is mathematically negative.
If newtime and oldtime are of the same unsigned type, the result will
never be negative, and (newtime - oldtime) will be the correct time
difference even when there's a wrap. Assuming ofcourse that the timer
wraps correctly, this will work in any kind of modulo arithmetic.
Whoever made this code originally probably knew what he was doing.

[ snip ]

--
... __o Øyvind
... _`\(, http://www.darkside.no/olr/
... (_)/(_) ... biciclare necesse est ...
Jun 27 '08 #11
On Tue, 13 May 2008 22:55:41 +0200, Øyvind Røtvold wrote:
fr*****************@boeing.com writes:
>On May 12, 3:58Â*pm, Bart <b...@freeuk.comwrote:
[ snip ]
>For an unsigned int, the value will wrap every 47 days. The original
code was

if ( (newtime - oldtime) < doubleclicktime ) {
/* perform double-click action */
}

That code is unsafe:

No.
>as oldtime approaches UINT_MAX, the risk is that newtime might occur
after time wraps, thus might be a small integer,

Yes.
>and (newtime - oldtime) is mathematically negative.

If newtime and oldtime are of the same unsigned type, the result will
never be negative, and (newtime - oldtime) will be the correct time
difference even when there's a wrap.
If newtime and oldtime are of the same unsigned type, *and that unsigned
type is unsigned int or wider*, then yes. It is unsigned int here,
apparently, so then it is safe, but it's not safe with smaller unsigned
types. If they were of type unsigned short, for example, it's very well
possible for newtime - oldtime to produce a negative result, because
newtime and oldtime will be promoted, typically to signed int, before any
subtraction takes place.
Jun 27 '08 #12

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

Similar topics

3
by: Kunle Odutola | last post by:
I have a database that tracks players for children's sports clubs. I have included representative DDL for this database at the end of this post. A single instance of this database supports...
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...
31
by: Spiro Trikaliotis | last post by:
Hello, I have a question regarding subtracting a pointer from another one. Assume I have two pointers p1 and p2, which both point to a memory area obtained with malloc(). Assume p1 = p2 + some...
3
by: Martin Joergensen | last post by:
Hi, Just a small problem (about taken the previous unsigned value in a 1D- array and copying it to the current value). Suppose there's an outer loop over the line shown below, so...
10
by: bg_ie | last post by:
Hi, I have a function which compares two unsigned ints and returns their difference in order to establish which is the greater of the two. int Compare(unsigned int time_left, unsigned int...
2
by: Frantic | last post by:
I'm working on a list of japaneese entities that contain the entity, the unicode hexadecimal code and the xml/sgml entity used for that entity. A unicode document is read into the program, then the...
6
by: clintonG | last post by:
Can anybody make sense of this crazy and inconsistent results? // IE7 Feed Reading View disabled displays this raw XML <?xml version="1.0" encoding="utf-8" ?> <!-- AT&T HTML entities & XML...
7
by: tempest | last post by:
Hi all. This is a rather long posting but I have some questions concerning the usage of character entities in XML documents and PCI security compliance. The company I work for is using a...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
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: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
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...

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.