Why are floating-point numbers directly compared in go standard library? [closed] - go

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 days ago.
Improve this question
In golang standard source code, file: src/math/dim.go
func max(x, y float64) float64 {
// special cases
switch {
case IsInf(x, 1) || IsInf(y, 1):
return Inf(1)
case IsNaN(x) || IsNaN(y):
return NaN()
case x == 0 && x == y:
if Signbit(x) {
return y
}
return x
}
if x > y {
return x
}
return y
}
related: https://floating-point-gui.de/errors/comparison/

The page you link to seems to suggest that you should avoid comparing floating point numbers. The reason is that if you do two widely different things depending on which one of two floating point numbers is bigger than the other, you might get surprises if the two numbers are almost equal but not quite, because rounding errors might mean that one of them is bigger than the other in a way that you do not expect.
Note that this is only a problem if you could do two very different things when comparing two very close floating point numbers.
What makes this implementation of max acceptable is that when the floating point numbers are very close to each other, you end up doing two things that are very close to each other as well (you are returning one of them), so you won't get any discontinuity issue.
Note however that you may still get unexpected behavior, like for instance
max(0.15 + 0.15, 0.1 + 0.2) == 0.3 may be false. But it's not a problem in the max function, it's a problem in what you do with the result.

Related

How to round to an arbitrary (non power-of-ten) precision [duplicate]

This question already has answers here:
Round to nearest multiple of a number
(3 answers)
Closed last year.
Let’s imagine I would like to round a number (i.e x = 7.4355) to a given arbitrary precision (i.e p = 0.002). In this case, I would expect to see:
round_arbitrary(x, p) = 7.436
What would be the best approach to design such a rounding function? Ideas in pseudocode or Rust are welcome
What would be the best approach to design such a rounding function?
An approach that gets near to OP's goal:
// Pseudo code (p != 0)
round_arbitrary(x, p)
x /= p
x = round(x)
return x*p
A key point is that floating point numbers are finite in size and so can represent about 264 different values exactly whereas code values like 7.4355, 0.002 and the math quotient 1/7.0 are of a much bigger set. Thus the above will get one close, but not certainty to an exact mathematically rounded value.
More advanced code would avoid overflow by not rounding large values which do not need rounding.
// Assume 0 < |p| < 1.0
round_arbitrary_2(x, p)
if (round(x) != x)
x /= p
x = round(x)
x *= p;
return x*p
Deeper
This issues lies with floating point numbers that are encoded with an integer times a power-of-2. Then the question is not so much "How to round to an arbitrary (non power-of-ten) precision", but "How to round to an arbitrary (non power-of-2) precision".

Comparing inequalities for Go bigInt? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am trying to compare two big ints. I'm looking at the docs: https://pkg.go.dev/math/big#Int and I don't see an inequality operator, but I do see an equality one (Cmp).
How am I meant to compare a big int a to a big int b?
Am I meant to subtract b from a and compare the sign? Or is there something I am missing? E.g.
c := (new.bigInt).Sub(a, b)
i := c.Sign()
if i < 0 {
fmt.Println("a < b")
}
It seems a little odd to me there is not an inequality operator, nor much about this online so I think I am doing something wrong.
Cmp returns: -1 if x < y, 0 if x == y, +1 if x > y
Go Playground Example

How to add a value in a matrix and make it decrease in radial way? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I got a matrix with odd lines and columns and all positions with 0 (zero) values, I want to add an X value (16 for example) at the center position of the matrix and make the other positions around to decrease an Y value (3 for example) but in a radial way, until those positions reach zero.
Like this image I created (I added colors just for better understanding):
I'm starting to work with matrices, I searched the web for something similar that could help but nothing very understandable. How that could be done? There is some for-loop trick to do this? Anyone had tried before? If someone could help I'll be grateful.
[EDIT]
So based on you're edit i thought this solution. Since you don't specify any programming language i'll use some c-like functional programming. I'll leave you the work of transforming it to object oriented if you need it.
Input:
Global maxtrix that starts in M[0,0] and ends in M[100'000, 100'000] (Note that, to make it easier to understand, i want check if i reach board, you should check)
Position for first number (X,Y) (in your example 5,5)
First number called N (in your example 16)
Decrement for along axis D (in your example 3)
main(){
computeValues(M, X, Y, N, D)
}
computeValues(M, X, Y, N, D){
M[X,Y] = N
if( N-D <= 0 ) return;
if( M[X,Y-1] == 0 ){
computeValues(M, X, Y-1, N-D, D)
}
if( M[X,Y+1] == 0 ){
computeValues(M, X, Y+1, N-D, D)
}
if( M[X-1,Y] == 0 ){
computeValues(M, X-1, Y, N-D, D)
}
if( M[X+1,Y] == 0 ){
computeValues(M, X+1, Y, N-D, D)
}
}
It should be pretty self-explanatory, anyway this function ends when reach 0 with the N-D <= 0 control. Once a position recive the number, it check for near position not yet evaluated and assign them N-D number, the new position if N-D <= 0 will continue to check for near position not evaluated and so on...
IMPORTANT NOTE: This function return the matrix as you asked in the text of your answer, which is a little bit different from the image you posted (Example M[4,4] in your example is 11 but it should be 10 and M[5,0] should be 1)
OLD ANSWER
This should not to much difficult. The only things you missed to say is how to compute value by value.
To accomplish this algorithm you need to know (and tell us, if you want) the rule or maybe the function that allow as to get the right value.
An example to make my point clearer:
Y
Y X Y
Y
If X=17 how do we know if Y, for example, need to be 15 or 14?
[If you edit you're answer whit those information i'll try to answer you properly]

Pascal decimal-point [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
could you please help me with my homework? I am just a beginner and know very little about Pascal :(
I am supposed to write a program for division but have special conditions depending on their decimal numbers. The outputs should look something like this:
no decimals then 20/5=4 (there can only be the 4; it can't be like 4.00)
if decimals then only 1 decimal number 9/4=2.3
if the decimal is an infinite of the same number then 1/3=0.(3)
How can I do it? I was thinking about putting it into an array but I don't know how to find where the decimal point is nor I know how to write the brackets into an output.
I can't manage to solve the 3rd point but here is the code for the first 2:
Var
x,y : integer;
z : real;
Begin
z := x / y;
if z = x div y
then Write(z:4:0) //Write a real var without any decimals
else Write(z:4:1); //Write a real var with just 1 decimal
End.
You'll have to change things around , like reading x and y , but from this code you can almost do your homework .
I'll try to solve the 3rd time , check the answer again after some time.
To solve 3rd point: think about x and y as about a fraction. Here is the basic idea:
A:=A/GCD(A,B);B:=B/GCD(A,B)
Integer part := A div B; A:=A mod B
Non-periodical part: while A mod 2=0 do BEGIN C:=C*2;A:=A div 2; END; while A mod 5=0 do BEGIN C:=C*5;A:=A div 5; END
Find M so that A*M=999..999.

How to numerically test stability of an oscillation curve? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I am now having an oscillation curve which is part of the solutions of a set of nonlinear ordinary differential equations. I am required to test the stability/convergence of this curve as time goes to infinite. How to do it with Matlab?
The figure looks like this:
It has been eight years since I did anything like this, so take my answer with a grain of salt.
Solve the equations using step size S and also with step size S/2; if the results match (i.e. are within machine epsilon, or 10x machine epsilon, or however you're defining the word "match"), then you're good to go on truncation error
Solve the equations using standard floating point arithmetic, and also solve them with extended precision arithmetic (IIRC Matlab calls this Variable Precision Arithmetic; IEEE double precision arithmetic uses a 52-bit significand, so an 80-bit significand ought to be more than enough to reveal instability due to roundoff error); if the results match, then you're good to go on roundoff error
I turned out using the following script, it works fine for me, but I am still wondering, is there any better way of predicting convergence at long time.
function err = stability_test(t, y)
% Given data of an oscillating curve y(t), tell whether the oscillation
% amplitude decrease or not by
% 1. locating peaking points
% 2. linear fit peak points and see if the gradient is negative or not
%
% t, y must be of the same shape
% err = 0, non-ocillating
% < 0, stable
% > 0, unstable
nt = linspace(min(t), max(t), 500);
ny = interp1(t,y,nt,'spline');
ndy = gradient(ny,nt);
ndy2 = del2(ny,nt);
if(isempty(find(ndy<0, 1)) || isempty(find(ndy2>0, 1)))
err = 0;
else
ndt = nt(2) - nt(1);
ii = find(abs(ndy)<abs(ndt*ndy2*2) & ndy2<0);
if(isempty(ii))
err = 0;
else
if(length(ii)==1)
ii = [ii,length(ndy)];
end
ym = ny(ii);
tm = nt(ii);
p = polyfit(tm, ym,1);
err = p(1);
end
end

Resources