我有一个简单的属性的setter方法,null不适合这个特定的属性.我总是在这种情况下被撕裂:我应该扔一个IllegalArgumentException,还是一个NullPointerException?从javadocs看,两者似乎都合适.有某种理解标准吗?或者这只是你应该做的任何事情之一,而且两者都是正确的?
java null exception nullpointerexception illegalargumentexception
在Java的构造函数中,如果要调用另一个构造函数(或超级构造函数),它必须是构造函数中的第一行.我假设这是因为在其他构造函数运行之前不应该允许修改任何实例变量.但是为什么你不能在构造函数委托之前有语句,以便计算其他函数的复杂值?我想不出任何好的理由,而且我遇到了一些真实的案例,我写了一些丑陋的代码来解决这个限制.
所以我只是想知道:
举一个我正在谈论的例子,考虑一下我在StackOverflow中给出的一些代码.在那段代码中,我有一个BigFraction类,它有一个BigInteger分子和一个BigInteger分母."规范"构造函数是BigFraction(BigInteger numerator, BigInteger denominator)表单.对于所有其他构造函数,我只是将输入参数转换为BigIntegers,并调用"规范"构造函数,因为我不想复制所有工作.
在某些情况下,这很容易; 例如,带两个longs 的构造函数是微不足道的:
public BigFraction(long numerator, long denominator)
{
this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
}
Run Code Online (Sandbox Code Playgroud)
但在其他情况下,这更难.考虑采用BigDecimal的构造函数:
public BigFraction(BigDecimal d)
{
this(d.scale() < 0 ? d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale())) : d.unscaledValue(),
d.scale() < 0 ? BigInteger.ONE : BigInteger.TEN.pow(d.scale()));
}
Run Code Online (Sandbox Code Playgroud)
我觉得这很难看,但它有助于我避免重复代码.以下是我想要做的,但它在Java中是非法的:
public BigFraction(BigDecimal d)
{
BigInteger numerator = null;
BigInteger denominator = null;
if(d.scale() < 0)
{
numerator = d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale()));
denominator = BigInteger.ONE;
}
else
{
numerator = d.unscaledValue();
denominator = BigInteger.TEN.pow(d.scale());
}
this(numerator, …Run Code Online (Sandbox Code Playgroud) 我认为java.math.BigDecimal应该是The Answer™需要用十进制数执行无限精度算术.
请考虑以下代码段:
import java.math.BigDecimal;
//...
final BigDecimal one = BigDecimal.ONE;
final BigDecimal three = BigDecimal.valueOf(3);
final BigDecimal third = one.divide(three);
assert third.multiply(three).equals(one); // this should pass, right?
Run Code Online (Sandbox Code Playgroud)
我希望assert通过,但事实上执行甚至没有到达那里:one.divide(three)原因ArithmeticException被抛出!
Exception in thread "main" java.lang.ArithmeticException:
Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide
Run Code Online (Sandbox Code Playgroud)
事实证明,API中明确记录了此行为:
在这种情况下
divide,准确的商可能有一个无限长的十进制扩展; 例如,1除以3.如果商具有非终止十进制扩展并且指定操作以返回精确结果,ArithmeticException则抛出a.否则,返回除法的确切结果,与其他操作一样.
进一步浏览API,人们发现实际上有各种重载divide执行不精确的划分,即:
final BigDecimal third = one.divide(three, 33, RoundingMode.DOWN);
System.out.println(three.multiply(third));
// prints "0.999999999999999999999999999999999"
Run Code Online (Sandbox Code Playgroud)
当然,现在显而易见的问题是"有什么意义?".BigDecimal当我们需要 …
我知道以下行为是一个老问题,但我仍然不明白.
System.out.println(0.1 + 0.1 + 0.1);
Run Code Online (Sandbox Code Playgroud)
或者即使我使用 BigDecimal
System.out.println(new BigDecimal(0.1).doubleValue()
+ new BigDecimal(0.1).doubleValue()
+ new BigDecimal(0.1).doubleValue());
Run Code Online (Sandbox Code Playgroud)
为什么这个结果是:0.30000000000000004而不是:0.3?
我怎么解决这个问题?
请考虑以下代码:
代码
public class RecursiveConstructor
{
//When this constructor is called
public RecursiveConstructor():this(One(), Two())
{
Console.WriteLine("Constructor one. Basic.");
}
public RecursiveConstructor(int i, int j)
{
Console.WriteLine("Constructor two.");
Console.WriteLine("Total = " + (i+j));
}
public static int One()
{
return 1;
}
public static int Two()
{
return 2;
}
}
Run Code Online (Sandbox Code Playgroud)
调用方法
public class RecursiveConstructorTest
{
public static void Main()
{
RecursiveConstructor recursiveConstructor = new RecursiveConstructor();
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
结果
构造函数二.
总数= 3
构造函数之一.基本.
为什么第二个构造函数首先运行?
我理解在链式构造函数中,我们首先调用基类构造函数,然后重新启动链,但是当构造函数保存在同一个类中时,为什么我们仍然会看到这个行为首先调用额外的构造函数?
我原以为最基本的构造函数内容会先执行.
由于计算机以"1"和"0"的形式思考,它们如何计算和表示7.50等分数?我知道Java和JavaScript,如果答案需要,你可以用它们作为例子.
编辑:我正在观看这部麻省理工学院视频,由科尔曼教授在46:31秒进行散列,他使用模块化轮子解释了乘法散列函数,模块化轮子是一个单位圆,其中有几个点,这些点表示分数.这促使我在这里问这个基本问题.
我在Java中有以下双重计算:
double C1 = some value; // It's always an integer
double C2 = some value; // It's always integer, and C2 >= C1
double S = some value; // It's always 0 < S <= 1
double carry = some value; // It's always 0 <= carry < 1
double rate = ((C1/C2)/S);
double C3 = Math.floor( (rate * S * C2) + carry );
Run Code Online (Sandbox Code Playgroud)
现在,如果我们没有失去精确度,那C3 == C1将是真的.但是,因为我们失去精度,将C3和C1仍然永远是平等的吗?
如果他们不会永远是平等的,如果我有C1,C2, …
我需要在Java中执行整数之间的划分,结果应该是一个浮点数.
我可以只使用/符号吗?如:
int integer1 = 1;
int integer2 = 2;
float quotient = integer1 / integer2; // Could I do this?
Run Code Online (Sandbox Code Playgroud) 在Java中计算和操作概率,然后将其表示为百分比时,用于表示它们的最佳数据结构是什么?
本机double并且float看起来不是特别理想的候选者,因为它们具有奇怪的舍入问题,当舍入发生多次并且变得复杂时可能引入错误.
BigInteger适用于计算排列和组合,BigDecimal看起来它可能是非整数值的一个很好的候选者,但有没有更适合处理百分比的东西?
注意:在这种情况下,计算的概率在性质上与涉及卡片的概率相似,但有数百张卡.对于更多的数学倾向,我特别使用多变量Hypergeometric_distributions.
给定一个浮点数,我希望得到一个String近似小数的有理数的表示(在给定的容差范围内ε很好).我目前的做法如下:
String rationalize(double d)
{
String s = Double.toString(d);
s = s.substring(s.indexOf('.')+1, s.length());
return s + " / " + ApintMath.pow(new Apint(10), s.length()).toString();
}
Run Code Online (Sandbox Code Playgroud)
如果你不熟悉它,ApintMath.pow即使使用任意长数也会工作,这很好,因为我试图转换小数位数千位的小数.我的算法的性能很糟糕.
我将此归结为两件事,但可能会有更多:
你会怎么做?还有其他我没有谈过的领域让我感到沮丧吗?