unsigned to signed integer convesion

Discussion in 'C Programming' started by junky_fellow@yahoo.co.in, Aug 8, 2005.

  1. Guest

    How the unsigned to signed integet conversion is done ?
    For eg:

    unsigned int ui = 100;
    int si = ui;

    What will be the value if "si" is printed ? How this conversion
    is done ?

    Thanx for any help in advance ....
    , Aug 8, 2005
    #1
    1. Advertising

  2. wrote:
    > How the unsigned to signed integet conversion is done ?
    > For eg:
    >
    > unsigned int ui = 100;
    > int si = ui;
    >
    > What will be the value if "si" is printed ? How this conversion
    > is done ?


    si will be 100, the value of ui is converted to the type of si (signed
    int) and the result is stored in si. If the value of ui is larger than
    INT_MAX (which it isn't in this case), overflow will occur during this
    conversion process resulting in undefined behavior.

    Robert Gamble
    Robert Gamble, Aug 8, 2005
    #2
    1. Advertising

  3. writes:
    > How the unsigned to signed integet conversion is done ?


    C99 6.3.1.3:

    When a value with integer type is converted to another integer
    type other than _Bool, if the value can be represented by the new
    type, it is unchanged.

    Otherwise, if the new type is unsigned, the value is converted by
    repeatedly adding or subtracting one more than the maximum value
    that can be represented in the new type until the value is in the
    range of the new type. (Footnote: The rules describe arithmetic
    on the mathematical value, not the value of a given type of
    expression.)

    Otherwise, the new type is signed and the value cannot be
    represented in it; either the result is implementation-defined or
    an implementation-defined signal is raised.

    > For eg:
    >
    > unsigned int ui = 100;
    > int si = ui;
    >
    > What will be the value if "si" is printed ? How this conversion
    > is done ?


    Since both unsigned int and int are guaranteed to be able to represent
    the value 100, the value of si will be 100.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Aug 8, 2005
    #3
  4. "Robert Gamble" <> writes:
    > wrote:
    >> How the unsigned to signed integet conversion is done ?
    >> For eg:
    >>
    >> unsigned int ui = 100;
    >> int si = ui;
    >>
    >> What will be the value if "si" is printed ? How this conversion
    >> is done ?

    >
    > si will be 100, the value of ui is converted to the type of si (signed
    > int) and the result is stored in si. If the value of ui is larger than
    > INT_MAX (which it isn't in this case), overflow will occur during this
    > conversion process resulting in undefined behavior.


    No, the rules for conversions are different from the rules for
    arithmetic operators.

    When converting a signed or unsigned type to an unsigned type,
    the result is well-defined (it wraps around).

    When converting a signed or unsigned type to an unsigned type, if the
    result can't be represented, either the result is
    implementation-defined or an implementation-defined signal is raised.
    No nasal demons are allowed.

    See my other response in this thread for the standard's definition.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Aug 8, 2005
    #4
  5. Eric Sosman Guest

    Keith Thompson wrote:
    > "Robert Gamble" <> writes:
    >
    >> wrote:
    >>
    >>>How the unsigned to signed integet conversion is done ?
    >>>For eg:
    >>>
    >>>unsigned int ui = 100;
    >>>int si = ui;
    >>>
    >>>What will be the value if "si" is printed ? How this conversion
    >>>is done ?

    >>
    >>si will be 100, the value of ui is converted to the type of si (signed
    >>int) and the result is stored in si. If the value of ui is larger than
    >>INT_MAX (which it isn't in this case), overflow will occur during this
    >>conversion process resulting in undefined behavior.

    >
    >
    > No, the rules for conversions are different from the rules for
    > arithmetic operators.
    >
    > When converting a signed or unsigned type to an unsigned type,
    > the result is well-defined (it wraps around).
    >
    > When converting a signed or unsigned type to an unsigned type, if the
    > result can't be represented, either the result is
    > implementation-defined or an implementation-defined signal is raised.
    > No nasal demons are allowed.


    The conversion doesn't yield undefined behavior, but
    it yields something very nearly as good (if that's the right
    word). The raising of the implementation-defined signal is
    the moment when the behavior becomes if not undefined at least
    unreliable. It's up to the implementation whether the signal
    is treated as if with SIG_IGN or SIG_DFL; it's also up to the
    implementation just what's involved in SIG_DFL for each signal.
    If you install a handler, things *do* become undefined:

    7.14.1.1/3
    [...] If and when the function returns, if the value
    of sig is [any] value corresponding to a computational
    exception, the behavior is undefined; [...]

    So the only way to handle the signal without invoking U.B. is
    to terminate the program by calling abort() or _Exit() in the
    handler. The signal is fatal unless it is SIG_IGN'ed (if the
    implementation permits it) or SIG_DFL'ed with an implementation-
    defined handling that itself isn't fatal.

    So, yes: You're right, and the behavior is not undefined
    unless a signal handler tries to return. But that's a bit
    like the observation that falling from atop a forty-story
    building won't hurt you -- the fall is harmless, but watch
    out for that sudden stop at the bottom ...

    --
    Eric Sosman, Aug 8, 2005
    #5
  6. <> wrote in message
    news:...
    > How the unsigned to signed integet conversion is done ?
    > For eg:
    >
    > unsigned int ui = 100;
    > int si = ui;
    >
    > What will be the value if "si" is printed ? How this conversion
    > is done ?
    >
    > Thanx for any help in advance ....


    There's one more problem related to what's being discussed in "find out the
    problem" by me and others...
    It's all about the conversion.
    Shamefully, but I had to fix a few bugs in my recent code... The code was
    something like this:

    typedef uint unsigned int;

    void drawlineh (int x, int y, uint len, uint color)
    {
    if (x+len < 0)
    return;
    // the rest of code that's properly working...
    }

    The problem is that x gets converted to unsigned int in the expression
    "x+len" and hence for negative x I wouldn't have the desired return from the
    function.
    This is really an annoying feature of C... The only way to make it work w/o
    changing the API (i.e. making len of type int too) is to do a cast:

    if (x+(int)len < 0)
    return;

    That makes me love asm more and more. Asm is the simplest programming
    language ever -- I always know what the code does and I know that for all
    bugs and problems it's me to blame. :) But C is such a wonderful creature,
    no surprise so many people get it all wrong. They have always been getting
    it wrong and they continue to do so. At times it's so counter intuitive for
    an HLL. And it seems like most (or all) the books on C that I had in the
    past never really described all this conversion well. I don't know if recent
    do (now's the time to get it right finally!), but these days I always check
    either in the standard or in the code if there's a doubt about something.
    Thankfully, I'm not writing bad code for I know many things outside the C
    scope... I don't wonder now that I should declare a variable before using it
    (Hello Basic, matlab, etc users!:), I don't wonder now about the range and
    precision of fixed and floating point things, etc etc.

    If I were to change C, I'd change the conversions/promotions to be more
    math-like, not C-like. But that's not going to happen anytime soon. Sigh.

    Alex
    Alexei A. Frounze, Aug 8, 2005
    #6
  7. Old Wolf Guest

    Alexei A. Frounze wrote:
    > if (x+len < 0)
    > return;
    >
    > The problem is that x gets converted to unsigned int in the expression
    > "x+len" and hence for negative x I wouldn't have the desired return from the
    > function.
    > This is really an annoying feature of C... The only way to make it work w/o
    > changing the API (i.e. making len of type int too) is to do a cast:
    >
    > if (x+(int)len < 0)
    > return;


    What if len > INT_MAX ?

    > That makes me love asm more and more. Asm is the simplest programming
    > language ever -- I always know what the code does and I know that for all
    > bugs and problems it's me to blame. :)


    So how would you compare -2000000000 and +3000000000 in ASM,
    without something at least as complicated as you would do in C ?
    Old Wolf, Aug 8, 2005
    #7
  8. "Old Wolf" <> wrote in message
    news:...
    > Alexei A. Frounze wrote:
    > > if (x+len < 0)
    > > return;
    > >
    > > The problem is that x gets converted to unsigned int in the expression
    > > "x+len" and hence for negative x I wouldn't have the desired return from

    the
    > > function.
    > > This is really an annoying feature of C... The only way to make it work

    w/o
    > > changing the API (i.e. making len of type int too) is to do a cast:
    > >
    > > if (x+(int)len < 0)
    > > return;

    >
    > What if len > INT_MAX ?


    Right. And using long would help neither on msvc++ nor on gcc on x86.
    int=long there. Only long long would do, but I guess it would be _int64 or
    something in terms of m$.

    > > That makes me love asm more and more. Asm is the simplest programming
    > > language ever -- I always know what the code does and I know that for

    all
    > > bugs and problems it's me to blame. :)

    >
    > So how would you compare -2000000000 and +3000000000 in ASM,
    > without something at least as complicated as you would do in C ?


    At least I would know about it for sure, w/o special books and standards :)

    Am I the only who feels uncomfortable with certain aspects of C? Or is there
    anyone who understands a bit of my concerns?

    Alex
    Alexei A. Frounze, Aug 8, 2005
    #8
  9. On Tue, 9 Aug 2005 00:44:30 +0400, Alexei A. Frounze
    <> wrote:

    > Shamefully, but I had to fix a few bugs in my recent code... The code was
    > something like this:
    >
    > typedef uint unsigned int;
    >
    > void drawlineh (int x, int y, uint len, uint color)
    > {
    > if (x+len < 0)
    > return;
    > // the rest of code that's properly working...
    > }
    >
    > The problem is that x gets converted to unsigned int in the expression
    > "x+len" and hence for negative x I wouldn't have the desired return from the
    > function.


    Several popular compilers will warn you about that if you enable
    warnings, because the condition can never be true so the statements
    after it are unreachable.

    > This is really an annoying feature of C... The only way to make it work w/o
    > changing the API (i.e. making len of type int too) is to do a cast:
    >
    > if (x+(int)len < 0)
    > return;


    If that's what you mean then do it -- but if len is larger than MAXINT
    it will have undefined effect so you need to check for that first.

    > That makes me love asm more and more. Asm is the simplest programming
    > language ever -- I always know what the code does and I know that for all
    > bugs and problems it's me to blame. :)


    And is totally non-portable. Even between assemblers for the same
    platform.

    > But C is such a wonderful creature,
    > no surprise so many people get it all wrong. They have always been getting
    > it wrong and they continue to do so. At times it's so counter intuitive for
    > an HLL.


    But different people find different parts of it counter-intuitive,
    that's the problem, and same is true for all other programming
    languages. Including asssembler.

    NOT R1
    BIC R1, R0

    instead of

    AND R1, R0

    And many other oddities which only make sense if you know a particular
    processor in detail.

    > And it seems like most (or all) the books on C that I had in the
    > past never really described all this conversion well. I don't know if recent
    > do (now's the time to get it right finally!), but these days I always check
    > either in the standard or in the code if there's a doubt about something.


    Yup. At least the C standard is clearer than the C++ standard...

    > Thankfully, I'm not writing bad code for I know many things outside the C
    > scope... I don't wonder now that I should declare a variable before using it
    > (Hello Basic, matlab, etc users!:), I don't wonder now about the range and
    > precision of fixed and floating point things, etc etc.
    >
    > If I were to change C, I'd change the conversions/promotions to be more
    > math-like, not C-like. But that's not going to happen anytime soon. Sigh.


    And would confuse many more. C was written for systems programmers,
    largely, and so was designed tro do what you told it and nothing more.
    So if you want to do some conversions other than the default, you do
    them. C is not designed for mathematics (try FORTRAN -- "FORmula
    TRANslation"), so you get 1/2 == 0 because that is what is expected in
    integer arithmetic even though it isn't in mathematics, and if you then
    assign the result to a floating point variable it sets it to zero.

    It's certainly not perfect, at least one of the original authors of the
    language has admitted that the precedence of some of the operators was
    wrong, but there is by now no chance of changing it because there is too
    much code which depends on it. Just as with natural language, we can't
    just change English spelling to something more lojikal at a wim, evn tho
    sum pepl hav trid to do that. Except it's worse with computer languages
    because you can probably understand what I wrote where a compiler
    can't...

    (And yes, I know that the Cyrillic alphabet did have several letters
    removed as an act of the government, but that can only be done when the
    government can say that all books in the previous script have to be
    replaced and be obeyed...)

    Chris C
    Chris Croughton, Aug 8, 2005
    #9
  10. "Alexei A. Frounze" <> writes:
    > "Old Wolf" <> wrote in message
    > news:...

    [...]
    >> So how would you compare -2000000000 and +3000000000 in ASM,
    >> without something at least as complicated as you would do in C ?

    >
    > At least I would know about it for sure, w/o special books and standards :)


    There are no special books for assembly language?

    > Am I the only who feels uncomfortable with certain aspects of C? Or is there
    > anyone who understands a bit of my concerns?


    I'd be suspicious of anyone who *wasn't* uncomfortable with some
    aspects of C. K&R themselves (or at least K and/or R) have expressed
    misgivings about some of the design choices.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Aug 9, 2005
    #10
  11. CBFalconer Guest

    "Alexei A. Frounze" wrote:
    >

    .... snip ...
    >
    > Shamefully, but I had to fix a few bugs in my recent code... The
    > code was something like this:
    >
    > typedef uint unsigned int;
    >
    > void drawlineh (int x, int y, uint len, uint color)
    > {
    > if (x+len < 0)
    > return;
    > // the rest of code that's properly working...
    > }
    >
    > The problem is that x gets converted to unsigned int in the
    > expression "x+len" and hence for negative x I wouldn't have the
    > desired return from the function.


    You can eliminate any positive values of x in the first place:

    if ((x < 0) && (-x < len)) return;
    else {
    ...
    }

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Aug 9, 2005
    #11
  12. On Tue, 09 Aug 2005 00:56:12 +0000, CBFalconer wrote:

    > "Alexei A. Frounze" wrote:
    >>

    > ... snip ...
    >>
    >> Shamefully, but I had to fix a few bugs in my recent code... The
    >> code was something like this:
    >>
    >> typedef uint unsigned int;
    >>
    >> void drawlineh (int x, int y, uint len, uint color)
    >> {
    >> if (x+len < 0)
    >> return;
    >> // the rest of code that's properly working...
    >> }
    >>
    >> The problem is that x gets converted to unsigned int in the
    >> expression "x+len" and hence for negative x I wouldn't have the
    >> desired return from the function.

    >
    > You can eliminate any positive values of x in the first place:
    >
    > if ((x < 0) && (-x < len)) return;
    > else {
    > ...
    > }


    That could still fail i.e. when x < -INT_MAX. Try

    if ((x < 0) && (x+len >= len)) return;

    This assumes that x+len isn't mathematically greater than UINT_MAX as does
    the original.

    Small challenge: when could x+len == len ? The code rules out x==0.

    Lawrence
    Lawrence Kirby, Aug 9, 2005
    #12
  13. Lawrence Kirby wrote:
    > CBFalconer wrote:
    > > "Alexei A. Frounze" wrote:
    > >> ...
    > >> typedef uint unsigned int;
    > >>
    > >> void drawlineh (int x, int y, uint len, uint color)
    > >> {
    > >> if (x+len < 0)
    > >> return;

    > >
    > > if ((x < 0) && (-x < len)) return;

    >
    > That could still fail i.e. when x < -INT_MAX. Try
    >
    > if ((x < 0) && (x+len >= len)) return;
    >
    > This assumes that x+len isn't mathematically greater than UINT_MAX


    Not sure what you mean here since, if x is negative and len is
    positive,
    then x+len can't 'mathematically' be greater than len, let alone
    UINT_MAX.

    > as does the original.
    > Small challenge: when could x+len == len ? The code rules out x==0.


    Spoiler: When x is INT_MIN, len = 0, and INT_MIN == 0u.

    The last condition occurs when...

    INT_MAX == UINT_MAX && INT_MIN == -INT_MAX - 1

    I.e. a twos complement system where the most negative int value is not
    a trap representation, and the sign bit of an int is a padding bit in
    the unsigned int representation.

    --
    Peter
    Peter Nilsson, Aug 10, 2005
    #13
  14. "Alexei A. Frounze" <> writes:
    > There's one more problem related to what's being discussed in "find
    > out the problem" by me and others... It's all about the conversion.
    > Shamefully, but I had to fix a few bugs in my recent code... The code
    > was something like this:
    >
    > typedef uint unsigned int;


    I guess you meant ``typedef unsigned int uint'' here.

    > void drawlineh (int x, int y, uint len, uint color)
    > {
    > if (x+len < 0)
    > return;
    > // the rest of code that's properly working...
    > }


    > The problem is that x gets converted to unsigned int in the expression
    > "x+len" and hence for negative x I wouldn't have the desired return
    > from the function. This is really an annoying feature of C... The
    > only way to make it work w/o changing the API (i.e. making len of type
    > int too) is to do a cast:
    >
    > if (x+(int)len < 0)
    > return;


    Unfortunately, then there are cases when you lose precision; i.e. when
    INT_MAX < UINT_MAX, which is usually the case (at least, on all the
    machines I've worked with).
    Giorgos Keramidas, Aug 11, 2005
    #14
  15. On Mon, 8 Aug 2005 23:32:34 +0100, Chris Croughton
    <> wrote:

    > On Tue, 9 Aug 2005 00:44:30 +0400, Alexei A. Frounze
    > <> wrote:

    <snip>
    > But different people find different parts of [assembly] counter-intuitive,
    > that's the problem, and same is true for all other programming
    > languages. Including asssembler.
    >
    > NOT R1
    > BIC R1, R0
    >
    > instead of
    >
    > AND R1, R0
    >
    > And many other oddities which only make sense if you know a particular
    > processor in detail.
    >

    The only ISA I know with BIC is PDP-11, in which case the first insn
    should be _COM_.

    But on the PDP-8 (except models with EAE) you had AND but not IOR (or
    XOR/EOR) so had to construct it with something like:
    CLA ; clear accumulator (can omit in some cases where known clear)
    TAD x ; 2sComplement add, the only kind available
    AND y
    CIA ; 1sComplement then increment accumulator = 2sC negate
    TAD x
    TAD y
    ; x plus y minus (x and y) = x ior y

    or x plus y minus 2 times (x and y) = x xor y
    (where the 2 times can be done using rotate-left)

    <snip>
    > > If I were to change C, I'd change the conversions/promotions to be more
    > > math-like, not C-like. But that's not going to happen anytime soon. Sigh.

    >
    > And would confuse many more. C was written for systems programmers,
    > largely, and so was designed tro do what you told it and nothing more.
    > So if you want to do some conversions other than the default, you do
    > them. C is not designed for mathematics (try FORTRAN -- "FORmula
    > TRANslation"), so you get 1/2 == 0 because that is what is expected in
    > integer arithmetic even though it isn't in mathematics, and if you then
    > assign the result to a floating point variable it sets it to zero.
    >

    Although FORTRAN is the same here -- type of a (sub)expression
    including a literal is independent of context. In fact 3 / 4 gives 0
    is probably as frequently asked (relatively) on comp.lang.fortran as
    here, although dblvar = 3.1415926536 ! loses precision is more
    frequent, since floating literals default to single precision in Ftn
    not double as in C, and _some_ Ftn compilers "helpfully" fix this in
    _some_ (simpler) cases whereas I have heard of no C compilers that do.


    - David.Thompson1 at worldnet.att.net
    Dave Thompson, Aug 14, 2005
    #15
  16. "Chris Croughton" <> wrote in message
    news:...
    > On Tue, 9 Aug 2005 00:44:30 +0400, Alexei A. Frounze
    > <> wrote:
    >
    > > Shamefully, but I had to fix a few bugs in my recent code... The code

    was
    > > something like this:
    > >
    > > typedef uint unsigned int;
    > >
    > > void drawlineh (int x, int y, uint len, uint color)
    > > {
    > > if (x+len < 0)
    > > return;
    > > // the rest of code that's properly working...
    > > }
    > >
    > > The problem is that x gets converted to unsigned int in the expression
    > > "x+len" and hence for negative x I wouldn't have the desired return from

    the
    > > function.

    >
    > Several popular compilers will warn you about that if you enable
    > warnings, because the condition can never be true so the statements
    > after it are unreachable.
    >
    > > This is really an annoying feature of C... The only way to make it work

    w/o
    > > changing the API (i.e. making len of type int too) is to do a cast:
    > >
    > > if (x+(int)len < 0)
    > > return;

    >
    > If that's what you mean then do it -- but if len is larger than MAXINT
    > it will have undefined effect so you need to check for that first.


    Yep. The ugly thing gets in.

    > > That makes me love asm more and more. Asm is the simplest programming
    > > language ever -- I always know what the code does and I know that for

    all
    > > bugs and problems it's me to blame. :)

    >
    > And is totally non-portable. Even between assemblers for the same
    > platform.


    True, but for an experienced programmer such as I am, converting most of the
    source between TASM, MASM, NASM, (G)AS, etc etc, isn't a problem, rather a
    straightforward excersize.

    > > But C is such a wonderful creature,
    > > no surprise so many people get it all wrong. They have always been

    getting
    > > it wrong and they continue to do so. At times it's so counter intuitive

    for
    > > an HLL.

    >
    > But different people find different parts of it counter-intuitive,
    > that's the problem, and same is true for all other programming
    > languages. Including asssembler.
    >
    > NOT R1
    > BIC R1, R0
    >
    > instead of
    >
    > AND R1, R0


    While I understand what NOT and AND usually mean and do, BIC isn't in my
    vocabulary. What is it? BIt Clear, clears the specified pattern of bits?
    I'm not sure I see the point here other than doing essentially the same
    thing two slightly different ways.

    > And many other oddities which only make sense if you know a particular
    > processor in detail.


    That's fine :)

    > > If I were to change C, I'd change the conversions/promotions to be more
    > > math-like, not C-like. But that's not going to happen anytime soon.

    Sigh.
    >
    > And would confuse many more. C was written for systems programmers,
    > largely, and so was designed tro do what you told it and nothing more.


    That's how every language and machine work. All errors are commited by the
    engineers because when they fail translate the idea/algorithm into machine
    language. I don't see a problem here. Actually, having both signed and
    unsigned integer types in any language would be that "more" thing as most
    CPUs don't differentiate the two, it's not needed in 2's complemented
    addition, subtraction, comparison... The CPU simply sets/clears the carry
    and overflow flags and it is the programmer to give the meaning to these
    flags and sign bits. The sign starts matter when we do conversion to longer
    types (as it needs replication) and in multiply/divide/modulo operations.
    The rest, the bit logic, is the bit logic, it shouldn't and doesn't care
    about the meanings of the MSBits.

    > So if you want to do some conversions other than the default, you do
    > them. C is not designed for mathematics (try FORTRAN -- "FORmula
    > TRANslation"), so you get 1/2 == 0 because that is what is expected in
    > integer arithmetic even though it isn't in mathematics, and if you then
    > assign the result to a floating point variable it sets it to zero.


    That's fine. Actually, any decent mathematicion must understand this.

    > It's certainly not perfect, at least one of the original authors of the
    > language has admitted that the precedence of some of the operators was
    > wrong,


    like in:
    if (a & b == c) {}
    ?
    :)

    > but there is by now no chance of changing it because there is too
    > much code which depends on it. Just as with natural language, we can't
    > just change English spelling to something more lojikal at a wim, evn tho
    > sum pepl hav trid to do that.


    Wel, if ju rimuv ol thi unnidid nd komplikeitid stuf from thi langwidj, it'l
    bicum unridbl. Or turn in to something closer to, say, German. :)

    > Except it's worse with computer languages
    > because you can probably understand what I wrote where a compiler
    > can't...


    Ah stupid compilers... :) There's a joke in our company... Q: how to make
    such code, adding to which -10 dB of noise (or 32% of errors/bugs:), would
    still compile and work properly?

    > (And yes, I know that the Cyrillic alphabet did have several letters
    > removed as an act of the government, but that can only be done when the
    > government can say that all books in the previous script have to be
    > replaced and be obeyed...)


    If that was done to English, the world would benefit. But it can't be done
    because the price would IMO be even bigger contextuality. Currently, at
    least the spellings of different things are different. Can't imagine they
    would be identical. The whole language would need changes.

    Alex
    Alexei A. Frounze, Aug 22, 2005
    #16
  17. "Keith Thompson" <> wrote in message
    news:...
    > "Alexei A. Frounze" <> writes:
    > > "Old Wolf" <> wrote in message
    > > news:...

    > [...]
    > >> So how would you compare -2000000000 and +3000000000 in ASM,
    > >> without something at least as complicated as you would do in C ?

    > >
    > > At least I would know about it for sure, w/o special books and standards

    :)
    >
    > There are no special books for assembly language?


    There are. But there you know what you're dealing with. But C appears to
    most easy, at least at first glance. And that's a dangerous imagination that
    leads to bugs, since at first many wouldn't go into such subtle details and
    would either omit the important parts or not even have them in the C book at
    all, which is no surprise to me now. There used to be plenty of bad writers.

    > > Am I the only who feels uncomfortable with certain aspects of C? Or is

    there
    > > anyone who understands a bit of my concerns?

    >
    > I'd be suspicious of anyone who *wasn't* uncomfortable with some
    > aspects of C. K&R themselves (or at least K and/or R) have expressed
    > misgivings about some of the design choices.


    :) That gives me some confidence.

    Alex
    Alexei A. Frounze, Aug 22, 2005
    #17
  18. "CBFalconer" <> wrote in message
    news:...
    > "Alexei A. Frounze" wrote:

    ....
    > > typedef uint unsigned int;
    > >
    > > void drawlineh (int x, int y, uint len, uint color)
    > > {
    > > if (x+len < 0)
    > > return;
    > > // the rest of code that's properly working...
    > > }
    > >
    > > The problem is that x gets converted to unsigned int in the
    > > expression "x+len" and hence for negative x I wouldn't have the
    > > desired return from the function.

    >
    > You can eliminate any positive values of x in the first place:
    >
    > if ((x < 0) && (-x < len)) return;
    > else {
    > ...
    > }


    No, both negative and non-negative values are allowed for x, and len can be
    any positive or 0.
    That's exactly what I expect them to be. But I see what you mean...
    (x+len < 0) can be transformed in two cases:
    x >= 0: the original condition is always false
    x < 0: the original condition can be turned into:
    ((x < 0) && (-x > len))
    You put the wrong inequality sign (because (x+len<0) is equivalent to
    (len<-x) -- you get it by subtracting x from both sides).

    OK, this one is definetely better, though not ideal anyway. :)

    Alex
    Alexei A. Frounze, Aug 22, 2005
    #18
  19. "Giorgos Keramidas" <> wrote in message
    news:...
    > "Alexei A. Frounze" <> writes:

    ....
    > > typedef uint unsigned int;

    >
    > I guess you meant ``typedef unsigned int uint'' here.


    Sure.

    > > void drawlineh (int x, int y, uint len, uint color)
    > > {
    > > if (x+len < 0)
    > > return;
    > > // the rest of code that's properly working...
    > > }

    >
    > > The problem is that x gets converted to unsigned int in the expression
    > > "x+len" and hence for negative x I wouldn't have the desired return
    > > from the function. This is really an annoying feature of C... The
    > > only way to make it work w/o changing the API (i.e. making len of type
    > > int too) is to do a cast:
    > >
    > > if (x+(int)len < 0)
    > > return;

    >
    > Unfortunately, then there are cases when you lose precision; i.e. when
    > INT_MAX < UINT_MAX, which is usually the case (at least, on all the
    > machines I've worked with).


    As long as the above condition (after fixing it) tests correctly, there
    should be no loss of any precision.

    Alex
    Alexei A. Frounze, Aug 22, 2005
    #19
  20. "Dave Thompson" <> wrote in message
    news:...
    ....
    > The only ISA I know with BIC is PDP-11, in which case the first insn
    > should be _COM_.
    >
    > But on the PDP-8 (except models with EAE) you had AND but not IOR (or
    > XOR/EOR) so had to construct it with something like:
    > CLA ; clear accumulator (can omit in some cases where known clear)
    > TAD x ; 2sComplement add, the only kind available
    > AND y
    > CIA ; 1sComplement then increment accumulator = 2sC negate
    > TAD x
    > TAD y
    > ; x plus y minus (x and y) = x ior y
    >
    > or x plus y minus 2 times (x and y) = x xor y
    > (where the 2 times can be done using rotate-left)


    (x | y) == ~((~x) & (~y))
    and:
    (x & y) == ~((~x) | (~y))
    which was named after De Morgan, if I'm not mistaken.
    and
    (x ^ y) == ((~x)&y) | (x&(~y)) ==
    [
    ((~x)&y) == ~(x|(~y))
    (x&(~y)) == ~((~x)|y)
    ]
    == (~(x|(~y))) | (~((~x)|y)) through ORs and inversion only
    or
    == ~((~(~x)&y)) & (~(x&(~y))) through ANDs and inversion only

    Indeed, one may use addition/subtraction to convert between &, |, and ^:
    x+y == (x&y)+(x|y)
    and it's easy to see the correctness of the above: if at a given bit
    position the bits of x and y aren't both ones, the above is obviosly true:
    (0&1)+(0|1)==1, (0&0)+(0|0)==0. If they're both ones, then (1&1)+(1|1)==1+1.
    It should not be hard to prove the form with exclusive OR too:
    x+y == 2*(x&y)+(x^y). It's easy to see that (x&y)+(x^y) is identical to
    (x&y)+(x|y), when the bits of x and y at the same bit position aren't both
    ones. If they are both ones, a compensation is due. And it can be made by
    adding another (x&y) term.
    And, of course, it's easy to see that (x&y)+(x^y) == x|y.

    Alex
    Alexei A. Frounze, Aug 22, 2005
    #20
    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. Replies:
    14
    Views:
    2,090
    CBFalconer
    Jun 18, 2005
  2. Gary Wessle
    Replies:
    4
    Views:
    623
    Ian Collins
    Jul 29, 2006
  3. tom
    Replies:
    4
    Views:
    319
  4. pozz
    Replies:
    12
    Views:
    732
    Tim Rentsch
    Mar 20, 2011
  5. Lox
    Replies:
    13
    Views:
    2,244
    Joe Pfeiffer
    May 31, 2012
Loading...

Share This Page