Math Whiz? Formula for Absolute Value

I had it right if you didn’t mean no negative base numbers for the ^ function.
In which case I will leave you going “Dooh!” Homer Simpson style.

R=N*(N^0)

N^0 = 1, so R = N. As I explained in post #11, this is impossible.

Yup, sure did. Thought you had just done a superscript when you meant to do a subscript.

Your solution is impressive (not to mention the quantity of typing - wow!), but I see it takes at least 5 or more iterations to get to a reasonably close absolute value (we mostly deal with 2 decimals, but 6 is the program’s limit and we’d have to be good to there).

Unfortunately I didn’t mention one additional limitation of our crappy program because I didn’t think it would come up. We can’t feed it a formula of more than 128 characters, and it looks like getting a good approximation with this method is going to blow that limit out of the water pretty quick.

So you definitely won the battle, but the war may be lost.

My greatest appreciation for everyone who has taken the time to cogitate on this li’l conundrum. Another poster who seems to know his/her math seems to have proof (unintelligible to my pea brain, unfortunately) that given the parameters of the problem there can be no viable solution. If nothing else, I can print out this thread and tell my boss that if the SD cognoscenti can’t solve 'er, she ain’t solvable!

Two decimals of accuracy.

R= ((N*100)^1)/100
Try that.

R = ((N * 100)[sup]1[/sup])/100 = (N*100)/100 = N

That doesn’t work either… Were you trying for something else, maybe?

ultrafilter’s post #11 is (or should be) the last word on this.

The one thing he left out is your ability to use the ^ operator, so I’ll fill in that detail; suppose you have an expression made from numeric constants, +, -, *, /, and ^. We can break this up into a bunch of pieces which don’t use ^, and then combine those with ^. As noted by ultrafilter, the pieces which don’t use ^ are rational functions. Thus, we have an expression put together out of rational functions and ^. We shall prove by induction that any such expression which is well-defined on all inputs, under the restriction that ^ only takes positive integer exponents, defines a rational function of its input (and thus cannot define the absolute value function): the base case is trivial, where the expression is given directly as a rational function. In the inductive case, we are looking at e1^e2 where e1 and e2 are, by the induction hypothesis, rational functions of their input. For the total expression to be well-defined on all inputs, we need e2 to give only values which are positive integers. The only rational functions which do so are those which are constant. Thus, the expression e1^e2 will be equivalent to e1^n for some constant positive integer n, which will be a rational function (since e1 is). This completes the proof.

(If, incidentally, the ^ operator on your calculator does something other than crash and burn when given non-positive-integer exponents [like, maybe, for some crazy reason, return 0 to indicate failure], the proof fails (to be relevant), and you might be able to get by)

Oops! Actually, I retract this. I just realized that you meant XOR, not exponentiation. I should have assumed that first, actually, since after years of writing C code, I almost always read “^” as “XOR”. The one time I make an exception, I make a fool of myself. :smack:

Huh? How would XOR make things work out?

Ok I see what my mistake is. A negative raised to a even number is positive. Raise a negative to an odd exponent get a negative result. Mark it down as confusion taken too long to clear.

Ah, well, it doesn’t. :smack:

I had just punched it into Windows calculator for a few sample numbers without thinking, and it seemed to work - if I’d been paying attention, I would’ve noticed that Windows calculator conveniently always gives a result from XOR with the sign of the second argument in decimal mode, for some reason presumably known only to the calculator gods.

In actual two’s complement with 32-bit words, if we try, for example, -5, we get:

|-5| ~= ((-5*100)^1)/100 = (-500^1)/100 = (0xFFFFFE0C ^ 1)/100 = 0xFFFFFE0D / 100 = -499/100 = -4

Which obviously doesn’t work.

In short, nothing to see here! :stuck_out_tongue: Obviously if you can use XOR, you’d just want to use |a| = (a>>31)^(a + (a>>31)), as pulykamell suggested.

(x * x * -x) / (x * -x)

Bleh, nevermind.

Knowing that it’s a program, can we go the way of Captain Kirk in the Kobayashi Maru and “change the scenario”?

Have you tried to disassemble the program?
Is it possible that we can write other programs to manipulate the input or output of your calculator program?
What OS + hardware platform are we talking about?

(Or, maybe I should just let it go…)

This is a good point. What does this calculator do, in the event of an illegal input (such as an exponent other than a positive integer, or a number that’s too large)? If it’s anything other than crash-and-burn, as Indistinguishable says, then it’d be possible to kludge together the equivalent of a conditional. How exactly to do this, though, would depend on what exactly the calculator does.

A general note, if you do go this route: A kludge of this order will almost certainly not be portable, even to other machines which are supposed to be 100% compatible with what you’re using now. If you do write such a monstrosity of an absolute value function, be absolutely certain to leave a comment in the code saying that your implementation is badly broken, and that it should be replaced with a real abs() at the first opportunity. Or if your coding environment is so pathological that it doesn’t even allow comments (which at this point wouldn’t surprise me), then leave the comment on a post-it note stuck to the machine, or something. But don’t leave such an abomination to pounce without warning on the next generation who will have to use this machine (or even on yourself, next year when you’ve forgotten what you did now).

Before it would come to that I’d just write a new program. We’ve got all the needed tools, just thought it would be nice, not to mention delightfully sneaky, to bend the existing program to our collective will.

Besides, I just figured we were missing some perfectly obvious method to do it. But looks like we weren’t quite as thick as we assumed we were.

That’s the really annoying part. It does a very thorough job of parsing input for illegal conditions. I thought for sure I would beat it with:

(X ^ 2) ^ (1 / 2)

But it looked into my blackhearted attempt and spit it right back. I think I heard giggling coming from inside the machine.

  1. Look at your calculator. Does the display start with a little horizontal line?
  2. If so, multiply by -1.
  3. If not, don’t touch it.

Got the formula for calculating a logarithm? We could take the square of the input, get the logarithm, then halve it and re-calculate the exponent.

I know the OP is long gone, and ultrafilter and Chronos have given far more practical answers, but I’ve been toying with this problem on and off for the past few hours while taking breaks at work, and think i have a semi-answer.

If i is the input, you can get a pretty close approximation to |i| under the assumed conditions by using the following formula:



          2*2^(100i)   
|i| ~ { --------------  -  1 } * i
         2^(100i) + 1  


100 is arbitrary, just to guarantee the exponent is arbitrarily large. If i is positive, then 2^100i is a very large number N, so the fraction becomes 2N/(N+1), which is just a shade under 2. If i is negative, then 2^100i is a very tiny positive number n, so the fraction becomes 2n/(n+1), or a positive number just a shade over zero. Subtract 1 from either result, and you get numbers very close to -1 and +1, depending on the sign of i. Multiply this by i to get |i|.

This obviously fails if i is fairly small (that can be corrected by increasing the 100 in the exponent), and if i is large enough the calculator may not calculate the exponential, so it’s a rather impractical solution. I offer it only to give myself closure to a problem that has been monopolizing my thoughts this afernoon :slight_smile:

Simplifying your expression a tiny bit, we have |x| approximated as [1 - 2/(B^x+1)] * x, where B is very, very large (the level of largeness required being determined by the size of x and how accurate a result you want).

Of course, cute as that is, it depends crucially on the ability to use ^ with exponents which may be negative (not to mention non-integral), which the OP lacks.