Why the result is not the same? - operator-precedence

I don't understand why the result of:
4 / 3 * Math.PI * Math.pow(radio,3)
is different of:
(4 * Math.PI * Math.pow(radio,3)) / 3
I use this in a program to calculate the sphere's volume.

First, lets insert some extra brackets ... for illustrative purposes:
This code:
4 / 3 * Math.PI * Math.pow(radio,3)
is equivalent to
((4 / 3) * Math.PI) * Math.pow(radio,3)
In words ... first we divide 4 by 3, then we multiply it by Pi, then we multiply by radio to the power of 3.
Now lets look at the first sub-expression (4 / 3). Since the operands are both integers, this is an integer division, and it produces an integer answer. And that answer is 1. The answer you really need there is 1.33333... but that isn't an integer.
How to fix it? Changing either or both of the numbers to double literals will cause the division to be treated as a floating point (double) division, and that will you the best possible approximation to 4 thirds.
4.0 / 3.0 * Math.PI * Math.pow(radio,3)

First of all check for precedence of operator.
In your case precedence order is :
() > * > / (Note : this precedence is for C operators)
So for above operations result must be same for both cases.
Let's take
Case 1 :
4 / 3 * Math.PI * Math.pow(radio,3)
Here Math.PI = 3.14
Suppose Math.pow(radio , 3) = 10
In this scenario first multiplication will happen
result = 4*3.14*10 = 125.60000000000001
125.600/3 = 41.86666666666667
Case 2 :
'(4 * Math.PI * Math.pow(radio,3)) / 3'
Here first it will calculate () block then / operator
i.e (4 * Math.PI * Math.pow(radio,3))
Here again result will be same as before

Related

Please explain theorem 7 in Goldberg 91

Theorem 7
When β = 2, if m and n are integers with |m| < 2^(p - 1) and n has the special form n = 2^i + 2^j, then (m n) n = m, provided floating-point operations are exactly rounded.
If I post the whole proof here, it will be long, unreadable and ugly. So please click the link on the right, press ctrl + F, and find Theorem 7. There it is! Goldberg91
OK, I have to say, at least from my own perspective, the proof of theorem 7 is too weird to comprehend, although the author claims that it's ingenious.
What I can only understand is that m has at most 1 bit right of the binary point. Yes, I know that, but why so n*qbar will round to m consequently? I can't also understand the so-called "halfway case" and almost everything from that line on.
Any help is welcome, thank you in advance.
EDIT:
Interestingly, the first comment below has solved all my questions in a roll, and the second comment suggests me to narrow my post.
That's right. It's inhuman to ask a person to explain the whole proof. So now my question becomes this:
Why the initial unscaled m's low-order bit was 0(found in the paragraph below formula 9)? Shouldn't the most significant digit be zero instead of the least significant one? Does this have something to do with 'Big-endian' or 'Little-endian'?
First off, let's scale n by 2. n should be made greater than or equal to 2^p - 1, and less than 2^p. The scaled n will be donated by n'. Scaling won't make any difference. It is exponent that is modified, since numbers are in binary, and we just have to focus on the significand / mantissa.
Next, m is scaled, producing m', so that q' = m'/n', less than 1 and greater than 1/2 (In fact, I think there should be 1/2 < q' ≤ 1). Scaling like these are possible because the upper bounds are exactly double the lower bounds, and β = 2.
As we can see, 2^p - 1 ≤ n' < 2^p and 1/2 < q' < 1, while m' = q' * n'. Since q' and n' are positive, the maximum of m' is the product of n' and q''s maximums, that is 2^p * 1 = 2^p. Similarly, the minimum of m' is 2^p - 1 * 1/2 = 2^p - 2.
Now that 2^p - 2 < m' < 2^p, we can say p - 2 < log2(m') < p, so the number of digits to the right of the binary point will be either p-1 (this happens when log2(m') is between p-2 and p-1) or p (when log2(m') is greater than or equal to p-1). Thus, m' has at most one bit to the right of the binary point.
As Mark Dickinson has said, as a result, the difference between m' and the next precision-p float up/down is at least 1/2. So to show that a quantity will round to m', it's enough to show that it's within 1/4 of m'.
Besides that, "the halfway case", namely the case where that quantity is exactly 1/4 from m', worth a separate discussion: Since the initial unscaled m had |m| < 2*p - 1, it has at least one bit to the right of the binary point, due to the same reason as mentioned above. m is an integer, so all digits to the right of the binary point are zero. Certainly, its low-order bit is 0 for that reason. Because scaling doesn't have effect on the significand / mantissa, the low-order bit of m' is also 0.
Consequently, using round to even, which is adopted by the original author by writing "Throughout the rest of this paper, round to even will be used." above (You can use ctrl + F again to find it), m' + 1/4 (0.01 in binary) will round to m', since 0 is even.
That is, if q̄ = m n, to prove the theorem requires showing that
|n' * q̄ - m'| ≤ 1/4.
Update 1
q' is a rational number, and q' < 1, so we can suppose that q' = 0.q1 q2... in binary, where qi, where i= 1,2,3... are single digits that contains 0 or 1. Let q̂ = 0.q1 q2 ... qp 1. Be careful, this token is "q-hat", not "q-bar", and it's a new variable I've just introduced in.
Now, if we shift q̂ left by p + 1 digits, we'll get an integer, namely q1 q2 ... qp 1, because all bits are to the left of the binary point. I'll use N to donate this integer hereafter. As a result, |q̂ - q'| = |N / 2^(p + 1) - m' / n'|.
The lower-bit of N is 1, so we know N = 1 + (qp * 2^1 + qp-1 * 2^2 + ... + q1 * 2^p). Obviously, N is an odd integer. Originally, n = 2^i + 2^j. Since scaling a number is just multiplying or dividing it by 2, n' is still a sum of two exponents of 2. Let them be n' = 2^i' + 2^j'. For convenience, it's assumed that i' ≥ j'.
2^p - 1 ≤ n' < 2^p, so 2^p - 1 ≤ 2^i' + 2^j' < 2^p. As a result, i', which accounts for a higher proportion of n', must be p - 1. To make n' less than 2^p, j' mustn't equal to i'. For readability, let k = j', so k ≤ p - 2. Thus,
. (Replace all n by n', m by m')
I suggest you to use some scratch papers to verify this formula on your own.
Update 2
Take a look at the numerator |(2^(p - 1 - k) + 1) * N - 2^(p + 1 - k) * m'|. As we have proved, k ≤ p - 2, so p - 1 - k ≥ 1, ensuring 2^(p - 1 - k) and 2^(p + 1 - k) to be even. Both (2^(p - 1 - k) + 1) and N are odd, so (2^(p - 1 - k) + 1) * N is odd, while 2^(p + 1 - k) * m' is even, and an odd integer can't equal to an even one. Therefore, (2^(p - 1 - k) + 1) * N - 2^(p + 1 - k) * m' is a non-zero integer. It's absolute value, namely the numerator, is consequently guaranteed to be equal to or greater than 1. Hence,
|q̂ - q'| ≥ 1 / (n' * 2^(p + 1 - k)).
q' < 1, and q̄ < 1, so q' * q̄ < 1. As a result, (m' * q') * q̄ < m', that is, n' * q̄ < m. Consequently,
|n' * q̄ - m'|
= m' - n' * q̄
= n' * (q' - q̄)
/* Since q̄ only has a precision of p, it will be 0.q1 q2 ... qp. So q̄ = q̂ - 2^(- p - 1). */
= n' * {q' - [q̂ - 2^(- p - 1)]}
= n' * [q' - q̂ + 2^(- p - 1)]
/* Assume that q' < q̂. The case q > q̂ is not discussed. */
= n' * [- |q' - q̂| + 2^(- p - 1)]
/* Since |q̂ - q'| ≥ 1 / (n' * 2^(p + 1 - k)), - |q̂ - q'| ≤ - 1 / (n' * 2^(p + 1 - k)). So */
≤ n' * {- 1 / [n' * 2^(p + 1 - k)] + 2^(- p - 1)}
= n' * {2^(- p - 1) - 1 / [n' * 2^(p + 1 - k)]}
/* We know n' = 2^i' + 2^j' = 2^(p - 1) + 2^k */
= [2^(p - 1) + 2^k] * {2^(- p - 1) - 1 / {[2^(p - 1) + 2^k] * 2^(p + 1 - k)}}
/* The equation is becoming less as less readable. For brevity, insignificant algebraic steps are omitted. */
= 2^-2 + 2^(- p - 1 + k) - 1 / 2^(p + 1 - k)
= 1/4
By now, |n' * q̄ - m'| ≤ 1/4 have been established. As mentioned above, this proves the theorem.
Q.E.D.
Questions that still remain:
Why "the case q > q̂ is similar" ? I think things will be totally different without that minus!

SQL Server - single Inline Query - (decimal remainder of x/y (rounded to 6 characters) ) / z

Can I ask for help on a SQL Statement please, I have to do the calculation inline and cannot declare variables for it
Calculation:
-91000000 / 2700000 = -33.7037037037
I need the remainder (7037037037 - but only up to 6 characters ) to be multiplied by 15000
703703 / 15000 = Final Answer of 49.913533
I thought I could do this:
select cast(ParseName(abs(cast(-91000000 as decimal)/ 2700000 ) %1,1) as numeric(8,8)) / 15000
WITH cte AS
(
SELECT -91000000 AS x, 2700000 AS y
)
SELECT ABS(ROUND((CAST(x AS decimal) / CAST(y AS decimal)) - (x/y), 6)) * 1000000 / 15000 FROM CTE

Decimals to one decimal place in as3?

I randomly generate a decimal using:
private function randomNumber(min:Number, max:Number):Number
{
return Math.random() * (max - min) + min;
}
It comes out with something like 1.34235346435.
How can I convert it so that its 1.3.
You can round to one decimal place like this;
var newValue:Number = Math.round(oldValue * 10)/10
Or an arbitrary number of decimal places like this:
function round2(num:Number, decimals:int):Number
{
var m:int = Math.pow(10, decimals);
return Math.round(num * m) / m;
}
trace(round2(1.3231321321, 3)); //1.323
Just use the .toFixed or .toPrecision method, it doesn't have to be complicated (note that the number will become a string so you'll need to assign it to such or convert it back).
eg.
var numb:Number = 4.3265891;
var newnumb;
newnumb=numb.toFixed(2);//rounds to two decimal places, can be any number up to 20
trace(newnumb);//traces 4.33
newnumb=numb.toPrecision(3);//the 3 means round to the first 3 numbers, can be any number from 1 to 20
trace(newnumb);//traces 4.33
If you need Number as result and performance, I would say this solution is more efficient than the Math.pow()/Math.round() one. If you need 3 decimals just change 100 by 1000.
var myNumber:Number = 3.553366582;
myNumber = (( myNumber * 100 + 0.5) >> 0) / 100;
//trace = 3.55
demonstrating the rounding :
var myNumber:Number = 3.557366582;
myNumber = (( myNumber * 100 + 0.5) >> 0) / 100;
//trace = 3.56
use this instead
return Math.Round((Math.random() * (max - min) + min),1);
,1 will round up till 1 place
for 2 places of decimal you can use
return Math.Round((Math.random() * (max - min) + min),2);
I hope this helps now.

Generating random number from 0 to 10 including both

I heard of some Math.random() but I'm not sure about using it correctly. Number must be whole, so I suppose I'll need some rounding function.
Math.random produces a pseudo random number between [0;1[ (0 included, but 1 excluded)
To have an evenly distributed probability for all numbers between 0 and 10, you need to:
var a : int = Math.floor( Math.random() * 11 )
Math.random() returns a number between 0 - 1. Multiply it with 10 an round it using an int.
// random number between 1- 10
var randomRounded : int = Math.round(Math.random() * 10);
Edit: more accurate version
// more accurate
var randomRounded : int = Math.floor(Math.random() * 11);
Math.round(Math.random()*10); maybe?

Determine longitudes and latitudes within a range

I have locations in my database. A location has the attributes latitude and longitude (taken from google maps, example: 48.809591).
Is there any query that could help me retrieve the locations within a range of another location?
Example:
I have the location A with latitude = 48.809591, and longitude = 2.124009 and want to retrieve all location objects in my database that are within 5 miles of location A
My first thought was to retrieve the locations in a square where location.latitude < A.latitude + 5 miles and location.latitude > A.latitude - 5 miles and location.longitude < A.longitude + 5 miles and location.longitude > A.longitude - 5 miles, and then remove the irrelevant locations from the returned array with the help of something like http://www.movable-type.co.uk/scripts/latlong.html
Any ideas?
Just in case you're using MySQL as your DBMS1, you may be interested in checking out the following presentation:
Geo/Spatial Search with MySQL2 by Alexander Rubin
The author describes how you can use the Haversine Formula in MySQL to order spatial data by proximity and limit the results to a defined radius. More importantly, he also describes how to avoid a full table scan for such queries, using traditional indexes on the latitude and longitude columns.
1 Even if you aren't, this is still interesting and applicable.
2 There is also a pdf version of the presentation.
The calculation you want, i think, is called the great circle distance:
http://en.wikipedia.org/wiki/Great-circle_distance
You would need a distance function.
For SQL Server it would look something like this (note that distance is in kilometers),
CREATE FUNCTION distance
(
#startLatitude float,
#startLongitude float,
#endLatitude float,
#endLongitude float
)
RETURNS float
AS
BEGIN
DECLARE #distance float;
set #distance =
6371 * 2 * atn2(sqrt(power(sin(pi() / 180 * (#endLatitude - #startLatitude) / 2), 2) +
power(cos(#startLatitude * pi() / 180), 2) *
power(sin(pi() / 180 * (#endLongitude - #startLongitude) / 2), 2)),
sqrt(1 - power(sin(pi() / 180 * (#endLatitude - #startLatitude) / 2), 2) +
power(cos(#startLatitude * pi() / 180), 2) *
power(sin(pi() / 180 * (#endLongitude - #startLongitude) / 2), 2)));
RETURN #distance
END