3 Simple questions - Math for ABS(), Round()

1. May 14, 2014

128GB

3 Simple questions -- Math for ABS(), Round()

To find the absolute value of a number you can use this
((x ^ 2) ^ 0.5)

To round a number up you can use this
-(((-x - 1) - ((-x - 1) % 1)) + 1)

To round a number down
(x - (x % 1))

Are there better ways to do this? The middle one is the one I'm thinking should somehow be shorter
This is for a program I'm making so it needs to be in normal text format please

2. May 14, 2014

phinds

Not unless you want to possibly get errors. Since computers have a limited number of bits to work with, there will be numbers for which x is NOT equal TO (x^2)^.5 due to rounding errors

Come to think of it, your other formulas might have the same flaw although probably with fewer manifestations.

I just use the intrinsic functions in whatever language I'm programming it. I figure the compiler writers probably got it done as well as I'll be able to.

3. May 14, 2014

jbunniii

In addition to the precision problem noted by phinds, this is also a terribly inefficient way to calculate the absolute value of a number. Squaring requires a multiplication, and the square root is far worse. Either use the built-in operator or, if there isn't one, then provide a simple one. An implementation in C++ could look like

Code (Text):

double abs_d(double x)
{
if (x >= 0)
return x;
else
return -x;
}

If you declare it inline, then it should be about as efficient as you're going to get.

For the rounding operations, note that the "% 1" operation could be expensive depending on how the compiler implements it. It might also give the wrong result for negative numbers, depending on the language. Check whether your language/library provides floor and ceil functions; no point reinventing the wheel. These functions are more likely to get all the IEEE floating point corner cases right, and they may give you access to floating point hardware instructions if available.

4. May 14, 2014

128GB

I do have reasons for "reinventing the wheel" because I am modifying them, I wanted to use the actually math not
if x >= 0 then
return x
else
return -x
end --This is lua by the way

I wanted to recreate the math library for modifying
if I did it like that instead of the math for abs, then I couldn't just copy paste the same function with a different math problem to create floor and ceil

5. May 14, 2014

.Scott

#define abs(x) ((x<0)?-x:x)

But use the library.

6. May 14, 2014

jbunniii

This fails due to unintended side effects if someone writes something like y = abs(++x). Both x and y will have the wrong values after this invocation.

7. May 14, 2014

AlephZero

It doesn't even work for y = abs(x) if x and y are complex numbers.

And don't even try to understand the error message(s) you might get if x is a user-defined type!

8. May 14, 2014

jbunniii

Actually, it even fails for something like abs(-1) since the macro didn't use enough parentheses. So abs(-1) expands as

(-1<0)?--1:-1

which is a syntax error.

9. May 14, 2014

AlephZero

Unless you have a compiler bug, and --1 evaluates to -2.

10. May 14, 2014

gsal

Excuse my ignorance (and allow me to play Devil's Advocate, if I can make sense)

I don't quite understand your problem or your request, you say "Math for Abs() and Round()"; but, what exactly do you call math? I mean, you are using basic math operators, alright, but you are also using %...so, what's wrong with using abs()? What if programmers had used the single non-alphabetic character "|" to express the unary "operator" absolute value of a number, |x ? would you be looking for a mathematical expression for it, too, then? Or would you be content with it?

Have you looked into how abs() is typically implemented, in the first place?
Is it done mathematically? I presume not, otherwise you wouldn't be asking?
So, who is to say that every mathematical function can be expressed mathematically, whatever that means?
I mean, it is not like every function is simply a short hand or abbreviation for some purely mathematical expression. is it?

By the way, what exactly you are planning of implementing again? As mention before, your expressions may not evaluate well under certain conditions...how about working with integers? what are you going to do with the result from ^0.5 ? How are you going to know that you need to return an integer? and are you going to round up or down? what's the result? 1.9999? 2.00001?

Another "by the way", have you tried defining your own abs() function? I once had Fortran function called pow() (it is not an intrinsic in Fortran) just to realized that is was somehow over writting the 'behind-the-scenes' C-function pow() that apparently was being used to implement Fortran's exponentiation operation '**'

What I am trying to say, in the previous paragraph, is that you may find that you can simply put your own functions in front of the intrinsic ones and you are done. Is this not good enough? does it not accomplish what you want?

Anyway, just asking questions as I feel the problem was not fully constraint in my opinion.

gsal