Math Whiz? Formula for Absolute Value

For an oddball problem at work I have a need to calculate the absolute value of a number. I am dealing with a very primitive calculator that has +, -, *, / and a power/exponent function that will only accept positive integer exponents. The calculator can be programmed with a formula using these operators and accept a single input number.

For reasons far too unglamorous and boring to go into here, we need this primitive calculator to take as input a positive or negative number and return the absolute value as the result.

Try as we might, we can’t seem to come up with a formula for getting this done. Any math whiz out there who can tell us how, perhaps with some optional belittling of our puny little math-impaired brains?

Thanks!!

I don’t think it can be done with the conditions you have described.

Does the calculator have a square root function. You can if so, you can use the function:

square root ((input number)^2).

Do you have a square root function or can you use X^.5? If so you can just take the original number, square it, then take the square root of it. That should always return the absolute value.

Sorry, no square root. Only positive integer powers.

let x= input number
y = x[sup]2[/sup]

z[sub]0[/sub] = 2
z[sub]1[/sub] = (z[sub]0[/sub] + (y/z[sub]0[/sub])) / 2
z[sub]2[/sub] = (z[sub]1[/sub] + (y/z[sub]1[/sub])) / 2
etc.

determine how many steps you want to go through in the above iteration. let’s say you want to stop at z[sub]10[/sub]. It is trivial (but tedious) to write the formula for z[sub]10[/sub], e.g.



z[sub]2[/sub] = (((2 + (y/2)) / 2)+ (y/((2 + (y/2)) / 2))) / 2


These more complicated formulae that you can write… Can they include conditionals? Because the best way to write an absolute value function is to just say something like “if x < 0: x = -x”

Alternately, is there some restriction on the values which can be input to this absolute value function? If, for instance, it only needs to handle integers in the range [-10,10], then you could write a 20th-order polynomial which will return the correct value for every input. I really wouldn’t recommend this, though, both because a 20th-order polynomial is pretty clunky, and because for any other value than those it’s specifically designed for, it’ll go absolutely haywire.

The real answer is, if your calculator can’t do conditionals, and doesn’t have a built-in absolute value function, then you’re using the wrong tool for the job. Go yell at whoever you need to to get a different calculator.

There’s also a method to do this using a bit shift, an addition, and an exclusive or (XOR), but I assume that functionality will not be available on the calculator. Otherwise, for those curious, here’s the formula (assuming a 32-bit word. Otherwise, replace 31 with whatever your word length is minus one).

a = (a>>31)^(a + (a>>31));

No, the problem would indeed be trivial in that case.

Decimal numbers in the range of about positive to negative 99,999,999.99.

It’s actually an old program written for a piece of hardware. We don’t have the source, or I’d have skinned this cat pdq.

I worked through the z[sub]2[/sub] formula for an 8 input and came up with a result of 2.833. Not exactly close, so I gather I’m doing something wrong, or do I have to get out to z[sub]50[/sub] or so in order to get anywhere close? Or am I missing something entirely about the formula?

With the operators +, -, * and /, you can generate the set of rational functions (i.e., functions of the form P(x)/Q(x), where P and Q are both polynomial functions). Rational functions are differentiable at every point where they’re continuous. |x| is continuous at 0 and not differentiable there, so it’s not a rational function. You’re SOL.

x[sup]2[/sup] - (x + x[sup]2[/sup])
I thought this would do it, but it seems to return the opposite value.

Yes you did something wrong, I think you missed the “y = x[sup]2[/sup]” step in my instructions.



x = 8
y = 64
z0 = 2
z1 = (2 + 64 / 2) / 2 = 17
z2 = (17 + 64 / 17) / 2 = 10.38235294
z3 = (10.38235294 + 64 / 10.38235294) / 2 = 8.273329445
z4 = (8.273329445 + 64 / 8.273329445) / 2 = 8.00451505


x[sup]2[/sup] - (x + x[sup]2[/sup]) = x[sup]2[/sup] - x - x[sup]2[/sup] = -x

Not what the OP needs.

Here’s an expanded version of what I posted. Not a good way of doing it, but I can’t think of another way to solve your problem with the given constraints.

find absolute value of input x: square x and then use an approximation method to find the square root of the square of x

for z[sub]0[/sub], choose a value as close to x as possible to converge quickly. In my case, I just make a crappy guess, z[sub]0[/sub] = 2

z[sub]0[/sub] = 2

z[sub]n+1[/sub] = ((z[sub]n[/sub] + (x[sup]2[/sup] / z[sub]n[/sub])) / 2)

so, expanding:

z[sub]1[/sub] = ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2)

z[sub]2[/sub] = ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2)

z[sub]3[/sub] = ((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2)

z[sub]4[/sub] = ((((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2) + (x[sup]2[/sup] / ((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2))) / 2)

z[sub]5[/sub] = ((((((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2) + (x[sup]2[/sup] / ((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2))) / 2) + (x[sup]2[/sup] / ((((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2) + (x[sup]2[/sup] / ((((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2) + (x[sup]2[/sup] / ((((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2) + (x[sup]2[/sup] / ((z[sub]0[/sub] + (x[sup]2[/sup] / z[sub]0[/sub])) / 2))) / 2))) / 2))) / 2))) / 2)

etc.

Depending on how the calculator handles overflow conditions you might be able to exploit that to get absolute value.

For example, say the maximum number the calculator can hold is MAX_INT. And any operations that calculate a result higher than MAX_INT return MAX_INT instead. And operations that calculate a result lower than -MAX_INT return -MAX_INT instead.

Then you can get absolute value with the following formula:

abs(x) = x * ((x * MAX_INT) / MAX_INT)

Essentially the overflow condition can be used as a ceiling function, and once you have a ceiling function you can get absolute value. But all of this is highly dependent upon how your particular hardware handles overflow.

What if x is between -1 and 1?

I don’t think this is a math question so much as a hacking question.

From the math perspective, any function will be a polynomial on x. You need a function with a first derivative that is always 1 when x is positive and always -1 when X is negative. It is hard to see how you get get this with a polynomial, even if you allow for negative (but integral) exponenents.

What I would suggest is this: Many calculators treat the input 0 - - x the same as 0 - x. Or 0 - - - x the same as 0 - - x.

So I would play with it to see if you can get the calculator to disregard a leading minus sign before the input.

N= number input
L = variable
R= result

L= N*N
R= L^.5

R=(N*N)^.5

This works for what I take it to be you wish to do.

Well I missed the integer part.

N= Number input
R=Result
Eraser

I’m done for a while.