Java 作业 - 从我的计算中得到一些奇怪的值
Java assignment - getting some weird values from my calculations
我现在正在学习 Java,但我的一项作业让我很困惑。我被要求创建一个 class 指定笛卡尔平面第一象限中的坐标,并且只使用两个值:从所述点到原点 (0,0) 的距离和角度矢量绘制到 X 轴。到目前为止,该程序如下所示:
public class Point2 {
private double _radius;
private double _alpha;
public Point2 (int x, int y) {
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, x));
}
public Point2 (Point2 other) {
this._radius = other._radius;
this._alpha = other._alpha;
}
public int getX() {
return (int)(this._radius * Math.cos(Math.toRadians(this._alpha)));
}
public int getY() {
return (int)(this._radius * Math.sin(Math.toRadians(this._alpha)));
}
public void setX(int x) {
if(x > 0) {
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(this.getY(), 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY(), x));
}
}
public void setY(int y) {
if(y > 0) {
this._radius = Math.sqrt(Math.pow(this.getX(), 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, this.getX()));
}
}
public boolean equals(Point2 other) {
if(this._radius == other._radius && this._alpha == this._radius) {
return true;
} else {
return false;
}
}
public boolean isAbove(Point2 other) {
if(this.getY() > other.getY()) {
return true;
} else {
return false;
}
}
public boolean isUnder(Point2 other) {
if(this.getY() < other.getY()) {
return true;
} else {
return false;
}
}
public boolean isLeft(Point2 other) {
if(this.getX() < other.getX()) {
return true;
} else {
return false;
}
}
public boolean isRight(Point2 other) {
if(this.getX() > other.getX()) {
return true;
} else {
return false;
}
}
double distance(Point2 other) {
double dist = Math.sqrt(Math.pow(this.getX() - other.getX(), 2) + Math.pow(this.getY() - other.getY(), 2));
return dist;
}
public void move(int dX, int dY) {
if(this.getX() + dX > 0 && this.getY() + dY > 0) {
this._radius = Math.sqrt(Math.pow(this.getX() + dX, 2) + Math.pow(this.getY() + dY, 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY() + dY, this.getX() + dX));
}
}
public String toString() {
return "(" + _radius + "," + _alpha + ")";
}
}
无论如何,当我在给定 x 和 y 坐标的情况下创建此 class 的实例时会发生什么,这真的没有问题 - 计算结果正确,一切都很好。问题是当我尝试使用任何改变 X 或 Y 坐标的方法时。
例如,我会 运行 setX(10)
,当我 运行 getX()
,我会得到 9,但是当我 运行 setX(10)
一次,然后重新 运行 get(X)
,我会得到 10。move()
也是如此 - 调用方法一次 returns [的结果不准确=13=] 和 getY()
但使用相同参数调用该方法一次或两次以上将更正结果。
这很奇怪 - 几乎就像这里的计算不正确或存在舍入问题。有人知道吗?
您肯定 运行 存在舍入误差。解决这个问题的第一种方法是直接存储 x 和 y。通常存储计算数据不是一个好主意。但是,我假设这是不可能的。
您 运行 遇到了两个问题。
在此代码中:
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(this.getY(), 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY(), x));
请注意 this.getY()
取决于半径和 alpha。当您在第一次调用中更改半径时,您从 getY 获得的值在第二次调用中会有所不同!您想要缓存从 getY
:
返回的值
int y = this.getY();
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, x));
在setY中发现了同样的问题,getX改变了中函数。
您遇到的另一个问题是由于在 getX/getY 中将双精度转换为整数。 Java 通过截断来做到这一点:(int) 4.99999999
将变为 4
。使用 (int) Math.round(...)
(Math.round() returns a long if you pass a double 可能会获得更好的结果。
总结
- 如果可能,请更改您的代码以直接存储 x 和 y,您可以根据这些值计算角度和半径。
- 考虑 x 和 y 可以是非整数。为什么将它们限制为整数?
- 请注意,在您修改对象的过程中,对象的状态可能不一致,例如当您仅根据新的 x 值修改了半径时,调用
getY
是不安全的。
我现在正在学习 Java,但我的一项作业让我很困惑。我被要求创建一个 class 指定笛卡尔平面第一象限中的坐标,并且只使用两个值:从所述点到原点 (0,0) 的距离和角度矢量绘制到 X 轴。到目前为止,该程序如下所示:
public class Point2 {
private double _radius;
private double _alpha;
public Point2 (int x, int y) {
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, x));
}
public Point2 (Point2 other) {
this._radius = other._radius;
this._alpha = other._alpha;
}
public int getX() {
return (int)(this._radius * Math.cos(Math.toRadians(this._alpha)));
}
public int getY() {
return (int)(this._radius * Math.sin(Math.toRadians(this._alpha)));
}
public void setX(int x) {
if(x > 0) {
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(this.getY(), 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY(), x));
}
}
public void setY(int y) {
if(y > 0) {
this._radius = Math.sqrt(Math.pow(this.getX(), 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, this.getX()));
}
}
public boolean equals(Point2 other) {
if(this._radius == other._radius && this._alpha == this._radius) {
return true;
} else {
return false;
}
}
public boolean isAbove(Point2 other) {
if(this.getY() > other.getY()) {
return true;
} else {
return false;
}
}
public boolean isUnder(Point2 other) {
if(this.getY() < other.getY()) {
return true;
} else {
return false;
}
}
public boolean isLeft(Point2 other) {
if(this.getX() < other.getX()) {
return true;
} else {
return false;
}
}
public boolean isRight(Point2 other) {
if(this.getX() > other.getX()) {
return true;
} else {
return false;
}
}
double distance(Point2 other) {
double dist = Math.sqrt(Math.pow(this.getX() - other.getX(), 2) + Math.pow(this.getY() - other.getY(), 2));
return dist;
}
public void move(int dX, int dY) {
if(this.getX() + dX > 0 && this.getY() + dY > 0) {
this._radius = Math.sqrt(Math.pow(this.getX() + dX, 2) + Math.pow(this.getY() + dY, 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY() + dY, this.getX() + dX));
}
}
public String toString() {
return "(" + _radius + "," + _alpha + ")";
}
}
无论如何,当我在给定 x 和 y 坐标的情况下创建此 class 的实例时会发生什么,这真的没有问题 - 计算结果正确,一切都很好。问题是当我尝试使用任何改变 X 或 Y 坐标的方法时。
例如,我会 运行 setX(10)
,当我 运行 getX()
,我会得到 9,但是当我 运行 setX(10)
一次,然后重新 运行 get(X)
,我会得到 10。move()
也是如此 - 调用方法一次 returns [的结果不准确=13=] 和 getY()
但使用相同参数调用该方法一次或两次以上将更正结果。
这很奇怪 - 几乎就像这里的计算不正确或存在舍入问题。有人知道吗?
您肯定 运行 存在舍入误差。解决这个问题的第一种方法是直接存储 x 和 y。通常存储计算数据不是一个好主意。但是,我假设这是不可能的。
您 运行 遇到了两个问题。
在此代码中:
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(this.getY(), 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY(), x));
请注意 this.getY()
取决于半径和 alpha。当您在第一次调用中更改半径时,您从 getY 获得的值在第二次调用中会有所不同!您想要缓存从 getY
:
int y = this.getY();
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, x));
在setY中发现了同样的问题,getX改变了中函数。
您遇到的另一个问题是由于在 getX/getY 中将双精度转换为整数。 Java 通过截断来做到这一点:(int) 4.99999999
将变为 4
。使用 (int) Math.round(...)
(Math.round() returns a long if you pass a double 可能会获得更好的结果。
总结
- 如果可能,请更改您的代码以直接存储 x 和 y,您可以根据这些值计算角度和半径。
- 考虑 x 和 y 可以是非整数。为什么将它们限制为整数?
- 请注意,在您修改对象的过程中,对象的状态可能不一致,例如当您仅根据新的 x 值修改了半径时,调用
getY
是不安全的。