我是Java复杂概念的新手,我也知道这不是一个困难的问题,但是我知道我在做一些错误,这是我班上的一个方法,并且正在我的主要方法中提取其值,但显示NaN
这是方法:
protected static Map<String, Double> getSlaMetrics(List<Vm> vms) {
Map<String, Double> metrics = new HashMap<String, Double>();
List<Double> slaViolation = new LinkedList<Double>();
double totalAllocated = 0;
double totalRequested = 0;
double totalUnderAllocatedDueToMigration = 0;
for (Vm vm : vms) {
double vmTotalAllocated = 0;
double vmTotalRequested = 0;
double vmUnderAllocatedDueToMigration = 0;
double previousTime = -1;
double previousAllocated = 0;
double previousRequested = 0;
boolean previousIsInMigration = false;
for (VmStateHistoryEntry entry : vm.getStateHistory()) {
if (previousTime != -1) {
double timeDiff = entry.getTime() - previousTime;
vmTotalAllocated += previousAllocated * timeDiff;
vmTotalRequested += previousRequested * timeDiff;
if (previousAllocated < previousRequested) {
slaViolation.add((previousRequested - previousAllocated) / previousRequested);
if (previousIsInMigration) {
vmUnderAllocatedDueToMigration += (previousRequested - previousAllocated)
* timeDiff;
}
}
}
previousAllocated = entry.getAllocatedMips();
previousRequested = entry.getRequestedMips();
previousTime = entry.getTime();
previousIsInMigration = entry.isInMigration();
}
totalAllocated += vmTotalAllocated;
totalRequested += vmTotalRequested;
totalUnderAllocatedDueToMigration += vmUnderAllocatedDueToMigration;
}
metrics.put("overall", (totalRequested - totalAllocated) / totalRequested);
if (slaViolation.isEmpty()) {
metrics.put("average", 0.);
} else {
metrics.put("average", MathUtil.mean(slaViolation));
}
metrics.put("underallocated_migration", totalUnderAllocatedDueToMigration / totalRequested);
// metrics.put("sla_time_per_vm_with_migration", slaViolationTimePerVmWithMigration /
// totalTime);
// metrics.put("sla_time_per_vm_without_migration", slaViolationTimePerVmWithoutMigration /
// totalTime);
return metrics;
}
我正在尝试通过以下代码打印其值:
Map<String, Double> results = getSlaMetrics(vmList);
System.out.println("Overall Violations:" + results.get("overall"));
我知道这是一个基本问题,但是请不要介意。
答案 0 :(得分:2)
获得 NaN“不是数字” 表示我们试图将零除以零。将非零数字除以零将得到-Infinity
或Infinity
。
我会看一下这行,并确保不要将数字除以零。
metrics.put(“ overall”,(totalRequested-totalAllocated)/ totalRequested);
正如Ivan在下面的评论中提到的,让我们演示NaN
,-Infinity
和Infinity
System.out.println(0.0/0.0);
System.out.println(0/0.0);
System.out.println(-1/0.0);
System.out.println(1/0.0);
它产生以下输出:
NaN
NaN
-Infinity
Infinity
答案 1 :(得分:0)
这里的实际问题不在于Map及其方法,而在于代码。 如果您执行此代码,则控件将永远不会转到以下
if (previousTime != -1) {
double timeDiff = entry.getTime() - previousTime;
vmTotalAllocated += previousAllocated * timeDiff;
vmTotalRequested += previousRequested * timeDiff;
if (previousAllocated < previousRequested) {
slaViolation.add((previousRequested - previousAllocated) / previousRequested);
if (previousIsInMigration) {
vmUnderAllocatedDueToMigration += (previousRequested - previousAllocated)
* timeDiff;
}
}
因此在以下分配中分配的值为零
totalAllocated += vmTotalAllocated; // zero
totalRequested += vmTotalRequested; // zero
totalUnderAllocatedDueToMigration += vmUnderAllocatedDueToMigration; // zero
因此Map中的以下值为0.0 / 0.0,即NaN
metrics.put("overall", (totalRequested - totalAllocated) / totalRequested);
// Value in Map for Key "overall" is ==> 0.0 - 0.0/0.0 = NaN
因此,如果输出中包含NaN,就不足为奇了。