Sign preserving Vs value preserving

S

sophia.agnes

Dear all,

I was going through the book "C a software engineering approach by
darnell & Margolis" there was a section named sign preserving vs value
preserving

it is as follows

sign preserving rule:-
when signed and un signed objects meet in an expression, the result is
always unsigned

ex:- if a is an unsigned short whose value is 2,then the expression
a - 3 evaluates to a very large un signed value rather than
the signed value of -1

value preserving rule:-

This method converts unsigned chars and unsigned shorts to
int,assuming that the int type is larger than unsigned char and
unsigned short respectively. if int is not larger the object is
converted to unsigned int

assuming 16-bit shorts and 32-bit ints in the previous example,
a would be converted to int rather than unsigned int,so the result of
the expression would be -1

note that the difference between sign-preserving and value-preserving
rules only becomes manifest when an unsigned type is shorter than
int.

if both operands are unsigned ints, the result is unsigned, so that
the expression 2u-3u always evaluates to a large unsigned value

1) how valid is the above explanation?

2)is there any implementation where the int type is smaller in size
when compared to unsigned short and unsigned char?

3)Does the condition

sizeof(short) <= sizeof(int) <= sizeof(long)

always holds in ANSI-C ? or is it true for unsigned values ?
 
V

vippstar

Dear all,

I was going through the book "C a software engineering approach by
darnell & Margolis" there was a section named sign preserving vs value
preserving

it is as follows

sign preserving rule:-
when signed and un signed objects meet in an expression, the result is
always unsigned true

if both operands are unsigned ints, the result is unsigned, so that
the expression 2u-3u always evaluates to a large unsigned value
To be precise, its value is equal to UINT_MAX
1) how valid is the above explanation? valid.
2)is there any implementation where the int type is smaller in size
when compared to unsigned short and unsigned char? no, because your 3) is true
3)Does the condition

sizeof(short) <= sizeof(int) <= sizeof(long)

always holds in ANSI-C ? or is it true for unsigned values ?
yes.
 
P

Peter Nilsson

(e-mail address removed) wrote:>

true

No, it's false. Let's look at the OP's (snipped) example.

"ex:- if a is an unsigned short whose value is 2, then
the expression a - 3 evaluates to a very large un signed
value rather than the signed value of -1"

It depends on whether an unsigned short promotes to int
or to unsigned int, and that depends on whether unsigned
short values can be represented by an int.

If USHRT_MAX <= INT_MAX, then the value is -1, otherwise
unsigned short promotes to unsigned int and the value is
UINT_MAX.

Unless by ints you mean integers. Arithmetic on two
unsigned short values may be signed or unsigned for
reasons stated above.
To be precise, its value is equal to UINT_MAX
valid.

No, it's invalid. If you've been fooled it's probably
because unsigned short has the same width as unsigned
int on the implementations you've seen.

No addressable type is smaller than a character type.
The standard has rules on the values that are representable
by types of the same signedness but different rank. It
has rules that the unsigned integer must be able to
represent all the non-negative values of it's signed
counterpart (same rank.)

It does not talk about the byte size of the representations
beyond imposing implicit minimums based on how many value
(and sign) bits are required to support the minimum range.
no, because your 3) is true

No, 3) is not necessarily true.
3)Does the condition

[Assuming a mathematical relation, rather than C's <=...]

No. The standard allows sizeof(short) > sizeof(int). All it
requires is that SHRT_MAX <= INT_MAX and INT_MIN <= SHRT_MIN.

You're not likely to find an implementation where shorts are
larger than ints, but the standard doesn't exclude them.
 
J

Jack Klein

Dear all,

I was going through the book "C a software engineering approach by
darnell & Margolis" there was a section named sign preserving vs value
preserving

it is as follows

sign preserving rule:-
when signed and un signed objects meet in an expression, the result is
always unsigned

ex:- if a is an unsigned short whose value is 2,then the expression
a - 3 evaluates to a very large un signed value rather than
the signed value of -1

value preserving rule:-

This method converts unsigned chars and unsigned shorts to
int,assuming that the int type is larger than unsigned char and
unsigned short respectively. if int is not larger the object is
converted to unsigned int

This is generally correct, on common implementations, but actually it
is technically incorrect. C's rules for conversions do not take into
account "larger", if by that you mean the size of various types in
bytes. The conversion rules are defined in terms of range of values.

When an unsigned type of lesser rank than int is undergoing default
promotions, it converts to signed int if signed int can represent all
the values of the lesser unsigned type. It converts to unsigned int
if signed int cannot represent all the values of the lesser type.

Note that this based on the maximum value that the lesser unsigned
type can hold, and not on whatever particular value it actually holds.
assuming 16-bit shorts and 32-bit ints in the previous example,
a would be converted to int rather than unsigned int,so the result of
the expression would be -1

note that the difference between sign-preserving and value-preserving
rules only becomes manifest when an unsigned type is shorter than
int.

The statement above is completely incorrect. Default promotions only
happen on unsigned types of lesser rank than int. But the usual
arithmetic conversions also use value preserving rules when different
arithmetic types are mixed in an operation.

Consider:

unsigned int ui;
signed long sl;

something_else = ui + sl;

On today's typical desktop systems, int and long are both 32-bit.
Since a signed long cannot represent the value UINT_MAX, both the
signed long and unsigned int are promoted to unsigned long, and that
is the type of the result of the addition.

But on a platform with 16-bit ints, still quite common in embedded
systems, a signed long can hold all the values of an unsigned int, so
the unsigned int is converted to signed long, the long itself
unconverted, and the result of the addition is a signed long.

The same thing can be true with mixing unsigned long and signed long
long types on C99 implementations.
if both operands are unsigned ints, the result is unsigned, so that
the expression 2u-3u always evaluates to a large unsigned value

1) how valid is the above explanation?

The basic idea is
2)is there any implementation where the int type is smaller in size
when compared to unsigned short and unsigned char?

3)Does the condition

sizeof(short) <= sizeof(int) <= sizeof(long)

always holds in ANSI-C ? or is it true for unsigned values ?

That is not a requirement of the C standard, which states nothing at
all about the relative sizes of the integer types. It only states
talks about ranges of values. The standard allows for an
implementation to have a short which occupies more bytes than an int,
using padding bits.

The standard integer types have an order:

signed char
signed short
signed int
signed long
signed long long

The standard requires that each type can hold all the values of the
types above it.

Each of the corresponding unsigned types has the same size as the
signed type.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
S

sophia.agnes

what about this result

when an integer value x is converted to a smaller unsigned integer
type, the result is the non negative remainder of

x/(U_MAX+1)

where U_MAX is the largest number that can be represented in the
shorter unsigned type.

i checked it using the following program

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>


int main(int argc, char* argv[])
{
unsigned short j;

j = 71124;
printf("\n USHRT_MAX = %d",USHRT_MAX);
printf("\n j = %d",j);
printf("\n ......... = %d",(71124) % (USHRT_MAX+1));

puts("");
return(EXIT_SUCCESS);
}

I got the o/p as

USHRT_MAX = 65535
j = 5588
......... = 5588
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top