I was wondering how would one record the previous value of a variable that changes. An example of this problem is this code down below:
int distanceFormula(int x1, int x2, int y1, int y2){
int distance;
distance = sqrt(pow((x1-x2), 2) + pow((y1-y2), 2));
return distance;
}
int main(){
for(int i = 0; i < 2; i++){
int x = rand() % 180;
int y = rand() % 180;
int x2 = rand() % 180;
int y2 = rand() % 180;
int distance = distanceFormula(x, x2, y, y2);
int priordistance = distanceFormula(x, x2, y, y2);
if(priordistance != distance){
cout<<"Yes! It worked!"<<endl;
}
}
return 0;
}
The code itself won't return "Yes! It worked!" How would one record the previous value of distance and then compare that previous value to the current value?
Edit:
Thanks for the fast comments! Really appreciate it.
To clarify the actual question, the code above is just a quick template/example. Since the value of distance will change upon the second loop around, how would one RECORD the first value of distance and set that value to priordistance and then compare the current value of distance to priordistance (whose value is really just the previous value of distance).
Simply redord the previous value in a variable.
#include <cmath>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
int distanceFormula(int x1, int x2, int y1, int y2){
int distance;
distance = sqrt(pow((x1-x2), 2) + pow((y1-y2), 2));
return distance;
}
int main(){
int priordistance = 0; // a variable used to record the value
for(int i = 0; i < 2; i++){
int x = rand() % 180;
int y = rand() % 180;
int x2 = rand() % 180;
int y2 = rand() % 180;
int distance = distanceFormula(x, x2, y, y2);
if(i > 0 && priordistance != distance){ // use i > 0 to avoid compareing with meaningless value
cout<<"Yes! It worked!"<<endl;
}
priordistance = distance; // record the value
}
return 0;
}
There is a few ways you could do this... you could define priordistance outside of your for loop, and be sure to only redefine it 1 time (since you are looping twice).
However this is not what I would do, I would simply create an array of integers that hold n number of 'distances' for your reference by index i
int[] or int *
You can do various things. You need the value to persist throughout your for loop. Note that there is no point in comparing until you have already got one prior value.
int main(){
int priordistance = 0; //lifetime outside for loop
for(int i = 0; i < 2; i++){
int x = rand() % 180;
int y = rand() % 180;
int x2 = rand() % 180;
int y2 = rand() % 180;
int distance = distanceFormula(x, x2, y, y2);
if(i && priordistance != distance){
//^---- have we got a prior value yet?
cout<<"Yes! It worked!"<<endl;
}
priordistance = distance;//remember for next time
}
return 0;
}
Do you mean something like the following?
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
int distanceFormula( int x1, int x2, int y1, int y2 )
{
int distance;
distance = std::sqrt( std::pow( x1 - x2, 2 ) + std::pow( y1 - y2, 2 ) );
return distance;
}
int main()
{
const size_t N = 2;
int distance[N];
std::srand( ( unsigned int )std::time( nullptr ) );
for ( size_t i = 0; i < N; i++ )
{
int x = rand() % 180;
int y = rand() % 180;
int x2 = rand() % 180;
int y2 = rand() % 180;
distance[i] = distanceFormula( x, x2, y, y2 );
}
if ( distance[0] != distance[1] ) std::cout << "Yes! It worked!" << std::endl;
return 0;
}
The program output is
Yes! It worked!
Related
I am writing code to determine if a polyline is self-intersecting or not.
If at least two links of a polyline intersect (at their internal points), it is called self-intersecting.
To begin with, I write a function to determine the intersection of two intersect segments. There I use the school straight line formula y = kx + b.
And then the function f, where I check every 2 points of 2 segments for intersection. In principle, everything works, but the code breaks when some part of the polyline does not exactly intersect, but simply "touches" some other segment of this polyline. For example, as in the test:
Test:
4
0 0
2 2
2 1
1 1
Code:
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("input.txt");
ofstream fout("output.txt");
class peresec{
public:
double x,y;
};
int intersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
double k1, k2, b1, b2, x, y, tmp;
if(x1>=x2) {tmp=x1; x1=x2; x2=tmp; tmp=y1; y1=y2; y2=tmp;}
if(x3>=x4) {tmp=x3; x3=x4; x4=tmp; tmp=y3; y3=y4; y4=tmp;}
if(y1==y2) k1=0; else k1 = ( y2 - y1 ) / ( x2 - x1 );
if(y3==y4) k2=0; else k2 = ( y4 - y3 ) / ( x4 - x3 );
if(k1 == k2) return 0;
b1=y1-k1*x1;
b2=y3-k2*x3;
x = (b2-b1)/(k1-k2);
y = k1*x + b1;
if(x1<=x && x3<=x && x2>=x && x4>=x && !((x==x1 && y==y1) || (x==x2 && y==y2) || (x==x3 && y==y3) || (x==x4 && y==y4)))
{return 1;}
else
return 0;
}
void f(peresec *a, int n)
{
int flag;
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
{
flag=intersect(a[i].x, a[i].y, a[(i + 1) % n].x, a[(i + 1) % n].y, a[j].x, a[j].y, a[(j + 1) % n].x, a[(j + 1) % n].y);
if(flag==1) {fout << 1; return;}
}
if(flag == 0){fout << 0; return;}
}
int main()
{
long long count;
peresec *a;
if( !(fin >> count)){fout<<0; return 0;}
fin.seekg(0);
fin >> count;
if(count == 0) {fout<<0; return 0;}
a = new peresec[count];
for(int i = 0; i < count; i++){ fin >> a[i].x; fin >> a[i].y;}
f(a,count);
return 0;
}
Then, having experienced a failure on this code, I decided to change the logic of the intersect function and did something like:
bool intersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
double v1, v2, v3, v4;
v1=(x4-x3)*(y1-y3)-(y4-y3)*(x1-x3);
v2=(x4-x3)*(y2-y3)-(y4-y3)*(x2-x3);
v3=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1);
v4=(x2-x1)*(y4-y1)-(y2-y1)*(x4-x1);
if((v1*v2<0) && (v3*v4<0)) return true;
else return false;
}
But even here the code breaks on this test. Should output 1 if there is a self-intersection, otherwise 0.
Most likely the problem is in the for loop in the function f. I've already tried everything.
I also tried this:
for (int i = 0; i < n - 1; i ++)
for (int j = i + 2; i < n; j ++)
Unfortunately, it did not help.
Can you explain why the code breaks???
I am afraid that you cannot always test this locally. In the example below, it is impossible to tell if there is a crossing or not without knowing the order of the links.
Another nasty case is when an endpoint falls "on" a link, and due to numerical inaccuracies, there could be zero or two intersections detected, or, even worse, only one. And adding tolerances does not help !
In order to resolve these difficult cases, you must first question the exact reason why you want to detect those self-intersections. Because the correct decisions are application-dependent.
This question already has answers here:
Calling a function in main
(4 answers)
Closed 4 years ago.
So I'm trying to make a simple pool ball simulation, and when trying to check the collision between balls, my bounce function is being skipped in the loop. There should be a display on the console with the random letters in the function bounce in the PoolTable.cpp file, but its skipped and doesn't process the hits or output the text to the console. Not sure why its not running the function. No warnings. No errors. compiles fine. Im on windows machine, using code blocks, and the GLUT library/project.
Walkthrough
So I initialize and place the balls with the constructor. Then I draw the balls on the screen with the drawBalls function. After drawing the balls, i update their positions and move them with moveBalls function. After moving each ball, while still in the moveball function, I check for collisions with checkCollisions function. checkCollisions then starts two for loops, but never runs the bounce function, as the balls don't bounce off eachother, and the cout isn't printed in the terminal. for some reason it is skipped.
PoolTable.cpp
#include "PoolTable.h"
#include "poolball.h"
#include "Graphics.h"
#include <iostream>
using namespace std;
#include <cmath>
PoolTable::PoolTable( int x){
placeBalls( x );
}
void PoolTable::placeBalls( int x ){
number_of_balls = x;
for( int i = 0; i < x; i++){
balls[i].setX( balls[i].getRadius() + i * 20 );
balls[i].setY( balls[i].getRadius() + i * 30 );
}
}
double find_angle(double vx, double vy) {
// determine the angle between poolballs when they collide
double t; double PI = acos(-1.0);
if(vx < 0) // vertical collision
t = PI + atan(vy/vx);
else if(vx > 0.0 && vy >= 0.0) // 1st quardant collision
t = atan(vy/vx);
else if(vx > 0.0 && vy < 0.0) //
t = 2.0*PI + atan(vy/vx);
else if( vx == 0.0 && vy == 0.0)
t = 0.0;
else if(vx == 0 && vy >= 0.0)
t = PI/2.0;
else
t = 1.5 * PI;
return t;
}
void PoolTable::bounce(int i, int j) {
cout << "klasdjflkadsjflkasjfsadk" << endl;
double PI = acos(-1.0);
double x1 = balls[i].getX();
double y1 = balls[i].getY();
double x2 = balls[j].getX();
double y2 = balls[j].getY();
double dx = x2 - x1;
double dy = y2 - y1;
double dist = sqrt(dx*dx+dy*dy);
// did a collision occur
if(dist <= 2 * balls[i].getRadius()) {
double phi; // angle between the two ball centers
if(dx == 0.0)
phi = PI/2.0;
else
phi = atan2 (dy, dx);
// now compute the total velocities of the two balls
double vx1 = balls[i].xSpeed;
double vy1 = balls[i].getYSpeed();
double v1total = sqrt(vx1*vx1 + vy1*vy1);
double vx2 = balls[j].getXSpeed();
double vy2 = balls[j].getYSpeed();
double v2total = sqrt(vx2*vx2 + vy2*vy2);
// find the angle of each ball's velocity
double ang1 = find_angle(vx1,vy1);
double ang2 = find_angle(vx2,vy2);
// transform velocities into normal.tangential components
double v1xr = v1total * cos(ang1 - phi);
double v1yr = v1total * sin(ang1 - phi);
double v2xr = v2total * cos(ang2 - phi);
double v2yr = v2total * sin(ang2 - phi);
// now find the final velocities (assuming equal mass)
double v1fxr = v2xr;
double v2fxr = v1xr;
double v1fyr = v1yr;
double v2fyr = v2yr;
// reset the velocities
balls[i].setXSpeed(cos(phi)*v1fxr + cos(phi+PI/2)*v1fyr);
balls[i].setYSpeed(sin(phi)*v1fxr + sin(phi+PI/2)*v1fyr);
balls[j].setXSpeed(cos(phi)*v2fxr + cos(phi+PI/2)*v2fyr);
balls[j].setYSpeed(sin(phi)*v2fxr + sin(phi+PI/2)*v2fyr);
}
}
void PoolTable::checkCollisions(void){
for( int i = 0; i < number_of_balls; i++){
for( int j = i + 1; j < number_of_balls; j++){
bounce(i, j);
}
}
}
void PoolTable::moveBalls(void){
for( int i = 0; i < number_of_balls; i++){
balls[i].move();
void checkCollisions();
}
}
void PoolTable::drawBalls(void){
for( int i = 0; i < number_of_balls; i++){
balls[i].draw();
}
}
void checkCollisions(); (in moveBalls) is a function prototype, not a function call. Remove the void.
I am trying to write a code to solve the n-body problem and i run into trouble when using an array with all the bodies instead of using the different bodies seperately. I currently have no idea what's going wrong in my code but when i plot x in function of y for any body i get a straight line which obviously isn't right.
This is my current code:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#define h 10000.0
#define N 3
#define G 6.67384*pow(10.0,-11)
using namespace std;
class particle{
public:
double kx1,kx2,kx3,kx4, kv1, kv2, kv3, kv4;
double ky1, ky2, ky3, ky4, kvy1, kvy2, kvy3, kvy4;
double x,y,vx,vy,m;
double dist(particle aap){
double dx = x - aap.x;
double dy = y - aap.y;
return sqrt(pow(dx,2.0)+pow(dy,2.0));
}
double g(double x1, double y1,particle aap){
return G*aap.m*(aap.x-x1)/pow(dist(aap),3.0);
}
double p(double x1, double y1, particle aap){
return G*aap.m*(aap.y-y1)/pow(dist(aap),3.0);
}
void update(){ //object advances 1 step
x = x + (1/6.0)*(kx1+2*kx2+2*kx3+kx4);
vx = vx + (1/6.0)*(kv1+2*kv2+2*kv3+kv4);
y = y + (1/6.0)*(ky1+2*ky2+2*ky3+ky4);
vy = vy + (1/6.0)*(kvy1+2*kvy2+2*kvy3+kvy4);
}
void create(double x1, double y1, double vx1, double vy1, double m1){
x = x1;
y = y1;
vx = vx1;
vy = vy1;
m =m1;
}
bool operator ==(particle &other){
if(x == other.x && y == other.y && vx == other.vx && vy == other.vy){
return true;
}
}
};
particle bodies[N];
void set(particle (&bodies)[N]){
bodies[0].create(1, 1, -2, 1, 2*pow(10.0,30));
bodies[1].create(2870671*pow(10.0,6), 0, 0, 6800, 8.6810*pow(10.0,25));
bodies[2].create(4498542*pow(10.0,6),0 ,0, 5430, 1.0243*pow(10.0,26));
}
double xforce(double x1, double y1, particle aap, particle bodies[N]){ //force in the x- direction
double fx = 0;
for (int i = 0; i <= N; i++){
if (bodies[i] == aap ){;}
else{
fx += aap.g(x1,y1,bodies[i]);
}
}
return fx;
}
double yforce(double x1, double y1, particle aap, particle bodies[N]){ //force in the y- direction
double fy = 0;
for (int i = 0; i <= N; i++){
if (bodies[i] == aap) {;}
else{
fy += aap.p(x1,y1,bodies[i]);
}
}
return fy;
}
void corr(double t, particle bodies[N]){ //runge kutta 4
for(int i =0; i <= N; i++){
bodies[i].kx1 = t*bodies[i].vx;
bodies[i].kv1 = t*xforce(bodies[i].x, bodies[i].y, bodies[i], bodies);
bodies[i].ky1 = t*bodies[i].vy;
bodies[i].kvy1 = t*yforce(bodies[i].x, bodies[i].y, bodies[i], bodies);
bodies[i].kx2 = t*(bodies[i].vx + 0.5*bodies[i].kv1);
bodies[i].kv2 = t*xforce(bodies[i].x + 0.5*bodies[i].kx1, bodies[i].y + 0.5*bodies[i].ky1, bodies[i], bodies);
bodies[i].ky2 = t*(bodies[i].vy + 0.5*bodies[i].kvy1);
bodies[i].kvy2 = t*yforce(bodies[i].x + 0.5*bodies[i].kx1, bodies[i].y + 0.5*bodies[i].ky1, bodies[i], bodies);
bodies[i].kx3 = t*(bodies[i].vx+ 0.5*bodies[i].kv2);
bodies[i].kv3 = t*xforce(bodies[i].x + 0.5*bodies[i].kx2, bodies[i].y + 0.5*bodies[i].ky2, bodies[i], bodies);
bodies[i].ky3 = t*(bodies[i].vy+ 0.5*bodies[i].kvy2);
bodies[i].kvy3 = t*yforce(bodies[i].x + 0.5*bodies[i].kx2, bodies[i].y + 0.5*bodies[i].ky2,bodies[i], bodies);
bodies[i].kx4 = t*(bodies[i].vx + bodies[i].kv3);
bodies[i].kv4 = t*xforce(bodies[i].x+ bodies[i].kx3, bodies[i].y + bodies[i].ky3, bodies[i], bodies);
bodies[i].ky4 = t*(bodies[i].vy + bodies[i].kvy3);
bodies[i].kvy4 = t*yforce(bodies[i].x + bodies[i].kx3, bodies[i].y + bodies[i].ky3, bodies[i], bodies);
}
}
void calculate(particle (&bodies)[N]){
set(bodies);
ofstream file;
file.open("tester.txt");
for(int i =0; i <=50000; i++){
corr(h, bodies);
for(int j = 0; j <= N; j++){
bodies[j].update();
}
if( i%1000 == 0){
file << i*h;
for(int j = 0; j <=N ; j++){
file <<" "<<bodies[j].x << " "<< bodies[j].y;
}
file <<" "<<"\n";
}
else{;}
}
file.close();
}
int main()
{
calculate(bodies);
system("pause");
return 0;
}
The problem probably lies outside of the class particle since the program worked before i started using the array bodies. Any suggestions for non essential improvements are ofcourse welcome. Another thing i'm trying to do is use std::vector instead of an array but i don't know how i could define a vector outside my functions like i defined the array bodies.
For a start, all of your i <= N are wrong, because your loop will execute 4 times (0, 1, 2, 3) instead of 3 for i < N.
You are likely experiencing energy drift, as RK4 is not symplectic, and the n-body problem is a Hamiltonian system. I had this same problem trying to use RK4 for a solar system n-body as well. So did this person. You should try another symplectic numerical method like Euler, Verlet, Ruth's 3rd, or Ruth's 4th order symplectic integrator.
What i want is that, I have info of 2 points, the starting x,y and mid point x,y and i need to find end line like until some kind of border, like window
here is what I do:
//function for calculating the end point from one location, to specific end location
//like a bullet moving forward in a line
//x,y start location(mouse), x2,y2(rect point location one of the 4) mid point, qx,qy end point(shadow or triangle draw location)
void screenEnd(int x, int y, int x2, int y2, int*qx,int*qy)
{
x = x2-x;
y = y2-y;
float tx = x2,ty = y2;
float result = atan2((float)y,(float)x) * 180 / PI;
float tempx = cos ( result * PI / 180.0 );
float tempy = sin ( result * PI / 180.0 );
bool check = true;
//this part needs optimization
while(check)
{
if(tx < 0|| ty < 0|| tx > 1280 || ty > 720)
{
check = false;
}
else
{
tx += tempx;
ty += tempy;
}
}
*qx = tx;
*qy = ty;
}
what I do is just increase point until it reaches the end.
Is there any way faster?
A classic window clipping task.
Consider a parametric equation where p is the point (x,y).
p(0) = x, y
p(0.5) = x2, y2
p(1) = x+2*(x2-x), y + 2*(y2-y)
p(t) = p(0) + t*(p(1) - p(0))
clip window = 0,0 to 720, 1280 (suspect you really want 719,1279)
The segment to draw initially ranges from t=0.0 to t=1.0. The segment is tested against each of the 4 sides of the bounding box, potentially reducing the t range. Maybe even eliminating all together.
Follows is some old code, enough to get you going.
#include <math.h>
int cliptest(int dz, int z, double *t0, double *t1) {
if (dz < 0) {
double t = ((double) z) / dz;
if (t > *t1)
return 0;
if (t > *t0)
*t0 = t;
} else if (dz > 0) {
double t = ((double) z) / dz;
if (t < *t0)
return 0;
if (t < *t1)
*t1 = t;
} else {
if (z < 0)
return 0;
}
return 1;
}
int clipper(int *px0, int *py0, int *px1, int *py1, int minx, int miny,
int maxx, int maxy) {
double t0, t1;
int dx, dy;
t0 = 0.0;
t1 = 1.0;
dy = *py1 - *py0;
dx = *px1 - *px0;
if (cliptest(-dx, *px0 - minx, &t0, &t1)
&& cliptest(dx, maxx - *px0, &t0, &t1)
&& cliptest(-dy, *py0 - miny, &t0, &t1)
&& cliptest(dy, maxy - *py0, &t0, &t1)) {
if (t1 < 1.0) {
*px1 = round(*px0 + t1*dx);
*py1 = round(*py0 + t1*dy);
}
if (t0 > 0.0) {
*px0 = round(*px0 + t0*dx);
*py0 = round(*py0 + t0*dy);
}
return 1;
}
return 0;
}
int x0 = x;
int y0 = y;
int x1 = x + 2*(x2-x); // Form end point
int y1 = x + 2*(y2-y);
if (clipper(&x0, &y0, &x1, &y1, 0, 0, 720, 1280))
Draw(x0, y0, x1, y2);
else
Handle_LineTotallyClippedOut();
Okay first of all, I am trying to implement the Perlin noise algorithm, and I managed to achived something strange, and I can't find the solution. I am using matlab to visualize the results I have already checked this question:
"Blocky" Perlin noise
I am doing it from this website:
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
And another website which I can't find right now but I will update as soon as I can.
So here are some pictures about the problem:
This is the problem if increase zoom
http://i.stack.imgur.com/KkD7u.png
And here are the .cpp-s:
//perlin.cpp
#include "Perlin_H.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <random>
using namespace std;
double Perlin::interp1(double a, double b, double x) {
double ft = x * 3.1415927;
double f = (1.0-cos(ft)) * 0.5;
//return (b-x > b-1/2) ? b-x : a+x;
return a * (1.0-f) + b * f;
}
double Perlin::smoothNoise(double x,double y) {
double corners = ( rand2(x-1, y-1)+rand2(x+1, y-1)+rand2(x-1, y+1)+rand2(x+1, y+1) ) / 16;
double sides = ( rand2(x-1, y) +rand2(x+1, y) +rand2(x, y-1) +rand2(x, y+1) ) / 8;
double center = rand2(x,y)/4;
return corners + sides +center;
}
double Perlin::lininterp1(double a,double b, double x) {
return a*(1-x) + b * x;
}
double Perlin::rand2(double x, double y) {
int n = (int)x + (int)y*57;
//n=pow((n<<13),n);
n=(n<<13)^n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
double Perlin::noise(double x, double y) {
double floorX = (double)floor(x);
double floorY = (double)floor(y);
double s,t,u,v;
s = smoothNoise(floorX,floorY);
t = smoothNoise(floorX+1,floorY);
u = smoothNoise(floorY,floorY+1);
v = smoothNoise(floorX+1,floorY+1);
double int1 = interp1(s,t,x-floorX);
double int2 = interp1(u,v,x-floorX);
return interp1(int1,int2,y-floorY);
}
//main.cpp
#include "Perlin_H.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <fstream>;
using namespace std;
int main() {
const int h=64,w=64,octaves=2;
double p=1/1;
double zoom = 30;
Perlin perlin;
double map[h][w];
ofstream output;
output.open("map.txt");
for(int i = 0; i < h ; i++) {
for(int j = 0; j < w ; j++) {
map[i][j] = 0;
}
}
double freq = 2;
for(int i = 0; i < h ; i++) {
for(int j = 0; j < w ; j++) {
double getnoise = 0;
for(int a=0; a < octaves; a++) {
double freq = pow(2,a);
double amp = pow(p,a);
getnoise = perlin.noise((((double)i)*freq)/zoom-(a*10),
((((double)j))*freq)/zoom+(a*10))*amp;
int color = (int)((getnoise * 128.0) + 128.0);
if(color > 255) color = 255;
if(color < 0) color = 0;
map[i][j] = color;
}
output << map[i][j] << "\t";
}
output << "\n";
}
output.close();
system("PAUSE");
return 0;
}
It's a typo!
s = smoothNoise(floorX,floorY);
t = smoothNoise(floorX+1,floorY);
u = smoothNoise(floorY,floorY+1);
v = smoothNoise(floorX+1,floorY+1);
Try:
u = smoothNoise(floorX, floorY +1)
This explains why the diagonal didn't have the blocky appearance (where x=y), and why many of the common feature shapes are subtly off in a mirrored and skewed fashion.
Since it is generally obvious that rand2(floor(y), floor(y)+1) != rand2(floor(x), floor(y+1)) the cell discontinuity will result.
Finding no mathematical error in your implementation, I suspect this is a number format issue.
Such block patterns are created when the grid point values are not actually the same when fetched from different sides - when rand2(floor(n) +1 ,y) != rand2(floor(n+1) ,y)
To fix it, declare floorX to be an int or long instead, and pass it as such to smoothNoise() and rand2().
This can happen due to floating point error in the representation of the Integer values floorX , floorX + 1. The epsilon of magnitude ulp or less can have either sign. the results of addition [floor(n) + 1] and flooring directly [floor(n+1)] are bound by different code, and so need not share a pattern of choosing which side to err on. When the results err on different sides, the int type cast strips the 0.99999999999 and the 0.0000000001 equally, treating the mathematically equivalent numbers as different.