Sign preserving Vs value preserving

Discussion in 'C Programming' started by sophia.agnes@gmail.com, Dec 5, 2007.

  1. Guest

    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 ?
    , Dec 5, 2007
    #1
    1. Advertising

  2. Guest

    On Dec 5, 1:44 pm, wrote:
    > 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.
    , Dec 5, 2007
    #2
    1. Advertising

  3. wrote:
    > wrote:>
    > > 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


    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.

    > > if both operands are unsigned ints, the result is
    > > unsigned,


    Unless by ints you mean integers. Arithmetic on two
    unsigned short values may be signed or unsigned for
    reasons stated above.

    > > 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.


    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.

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


    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
    >
    > > sizeof(short) <= sizeof(int) <= sizeof(long)


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

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

    >
    > yes.


    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.

    --
    Peter
    Peter Nilsson, Dec 5, 2007
    #3
  4. Jack Klein Guest

    On Wed, 5 Dec 2007 03:44:32 -0800 (PST), wrote
    in comp.lang.c:

    > 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
    Jack Klein, Dec 6, 2007
    #4
  5. Guest

    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
    , Dec 7, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?TWlrZQ==?=

    Preserving the value of an int between postbacks

    =?Utf-8?B?TWlrZQ==?=, May 11, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    5,225
    =?Utf-8?B?TWlrZQ==?=
    May 11, 2005
  2. Jimmy
    Replies:
    1
    Views:
    930
    Cowboy \(Gregory A. Beamer\)
    Nov 21, 2006
  3. TTroy
    Replies:
    16
    Views:
    787
    Peter Nilsson
    Jan 31, 2005
  4. Spiros Bousbouras

    Preserving the value of errno

    Spiros Bousbouras, Jul 30, 2007, in forum: C Programming
    Replies:
    15
    Views:
    547
    Spiros Bousbouras
    Aug 10, 2007
  5. Jimmy
    Replies:
    3
    Views:
    2,393
    shimmyshack
    Nov 20, 2006
Loading...

Share This Page