POV-Ray : Newsgroups : povray.general : Function: Making negative numbers positive : Re: Function: Making negative numbers positive Server Time
26 Jun 2024 13:48:04 EDT (-0400)
  Re: Function: Making negative numbers positive  
From: Todd Carnes
Date: 27 Nov 2015 17:46:06
Message: <5658dd2e$1@news.povray.org>
On 2015-11-27 11:28, clipka wrote:
>> That works too, but then it's really just masking the fact that you are
>> >doing what I said... i.e. multiplying by -1.
> No, actually it's just the other way round: Multiplication by -1 is a
> negation in a complicated disguise.
>
>
> Mathematically, the definition of the negative of a value x has nothing
> to do with multiplication whatsoever; instead, it is defined as the
> inverse of x regarding the addition, i.e. the value that, when added to
> x, will result in the neutral element 0.
>
> In other words, the expression
>
>      -x
>
> is defined such that:
>
>      x + (-x) = 0
>
> See? No multiplication involved there. As a matter of fact, in its most
> basic form the multiplication operation isn't even/defined/  for
> negative numbers; defining whether the product of two negative values
> should itself be negative or positive is actually a choice -- it doesn't
> follow from first principles (although the choice that such a product
> should be positive turns out to be helpful).
>
>
> In computing, too, arithmetic negation is a well-established operation
> in and of itself that has nothing to do with multiplication whatsoever.
> CPUs had arithmetic negation operations long before multiplications were
> implemented as dedicated machine code operations; earlier computers had
> to implement multiplications as a series of additions, but could negate
> with ease. And as a matter of fact, in the early days multiplication
> functions (and later machine code operations) were sometimes unable to
> deal with negative numbers entirely, and to compute the product of two
> numbers of arbitrary sign it would have been necessary to first
> determine the operands' signs and figure out whether the result should
> be negative, then negate any negative operands to get their absolute
> value, multiply those, and then negate the result again if it was
> supposed to be negative.
>
> In floating-point arithmetics as used by POV-Ray, numbers are typically
> stored in sign-and-magnitude format, i.e. there is a bit indicating the
> sign of the number, while all the other bits combined indicate the
> magnitude. Thus, arithmetic negation is as simple as flipping the sign
> bit. Multiplying a number by -1, on the other hand, is as complicated as
> multiplying the magnitudes of the operands, and setting the result's
> sign bit to the XOR of the operands' sign bits. In this context,
> multiplying by 1 is as complicated as multiplying by any other value,
> unless the compiler knows in advance that the value is 1 and can
> therefore optimize the operation.
>
>
> In POV-Ray, something even more surprising happens; let's look at the
> following statement:
>
>      #declare PositiveNumber = -1 * NegativeNumber;
>
> This is actually equivalent to:
>
>      #declare UNDEFINED_IDENTIFIER = -CONST * FLOAT_IDENTIFIER;
>
> where UNDEFINED_IDENTIFIER happens to be called "PositiveNumber" and is
> (presumably) undefined, CONST happens to be 1.0, and FLOAT_IDENTIFIER
> happens to be called "NegativeNumber" and (presumably) holds some
> negative number.
>
> As you may notice, this statement includes a negation_and_  a
> multiplication. The reason is that POV-Ray does not know negative
> constants - all it gives you is positive constants and a negation operator.
>
> (The same is also true in the C and C++ programming languages; in their
> case, there are even situations where this matters, and can mess up the
> code of unsuspecting programmers.)
>
> As POV-Ray is not an optimizing compiler (actually it's no compiler at
> all), it resolves the multiplication operation by blindly invoking the
> CPU's floating point multiplication machine code operation, even if one
> of the operands happens to be 1 in magnitude.
>
> Obviously, multiplying a number with a negated positive constant takes
> longer to execute than just negating the number in question -- and it
> also takes longer to parse, requiring at least two more tokens (the
> numeric literal "1" and the multiplication operator "*").
>

Thank you for taking the time to explain all this. It was actually much 
more complicated than I had first thought.

Todd


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.