我已经尝试了几天,以弄清楚为什么我的应用程序无法获得正确的输出。 logcat中没有错误显示,以解释输出为什么是“ NaN”而不是我尝试计算的值。有人可以告诉我我犯的错误吗?这是我最后一个学年项目的计算器应用程序,尽管效果不佳,我还是试图纠正该问题。
这是应用程序的主类。
我已经尝试过各种论坛上针对类似问题的建议。
public String educationStr, ethnicity, ldlStr, hdlStr, ageStr, tcStr, sysBPStr, diaBPStr;
public int married=0, education=0, educationSec=0, educationTert=0;
public int smoker=0, ethnicityChk=0;
public int highCholesterol=0;
public int atrialFibrillation=0;
public int familialCVD=0;
public int hypertension=0;
public int sex=0;
public int age=0;
public double tcVal = 0;
public double hdlVal=0;
public double ldlVal = 0;
public int sysBPval = 0;
public int diaBPval = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch_calculator);
//spinner for sex choices
Spinner spinnerSex = findViewById(R.id.sexSelect);
ArrayAdapter<CharSequence> adapterSex = ArrayAdapter.createFromResource(this, R.array.SexChoices, simple_spinner_item);
adapterSex.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerSex.setAdapter(adapterSex);
spinnerSex.setOnItemSelectedListener(this);
//spinner for marriage choices
Spinner spinnerMarried = findViewById(R.id.marriedSelect);
ArrayAdapter<CharSequence> adapterMarried = ArrayAdapter.createFromResource(this, R.array.YN, simple_spinner_item);
adapterMarried.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerMarried.setAdapter(adapterMarried);
spinnerMarried.setOnItemSelectedListener(this);
//spinner for Ethnicity
Spinner spinnerEthnicity = findViewById(R.id.ethnicitySelect);
ArrayAdapter<CharSequence> adapterEthnicity = ArrayAdapter.createFromResource(this, R.array.EthnicChoices, simple_spinner_item);
adapterEthnicity.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerEthnicity.setAdapter(adapterEthnicity);
spinnerEthnicity.setOnItemSelectedListener(this);
//spinner for education
Spinner spinnerEducation = findViewById(R.id.EduLevelSpin);
ArrayAdapter<CharSequence> adapterEducation = ArrayAdapter.createFromResource(this, R.array.EduLevel, simple_spinner_item);
adapterEducation.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerEducation.setAdapter(adapterEducation);
spinnerEducation.setOnItemSelectedListener(this);
//spinner for smoking history
Spinner spinnerSmoker = findViewById(R.id.smokerSelect);
ArrayAdapter<CharSequence> adapterSmoker = ArrayAdapter.createFromResource(this, R.array.smoke, simple_spinner_item);
adapterSmoker.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerSmoker.setAdapter(adapterSmoker);
spinnerSmoker.setOnItemSelectedListener(this);
//spinner for family health --> high cholesterol
Spinner spinnerHighCholesterol = findViewById(R.id.highCholesterolSelect);
ArrayAdapter<CharSequence> adapterHighCholesterol = ArrayAdapter.createFromResource(this, R.array.YN, simple_spinner_item);
adapterHighCholesterol.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerHighCholesterol.setAdapter(adapterHighCholesterol);
spinnerHighCholesterol.setOnItemSelectedListener(this);
//spinner for family health --> A Fib
Spinner spinnerAFib = findViewById(R.id.atrialFibrillationSelect);
ArrayAdapter<CharSequence> adapterAFib =
ArrayAdapter.createFromResource(this, R.array.YN, simple_spinner_item);
adapterAFib.setDropDownViewResource
(android.R.layout.simple_spinner_dropdown
item);
spinnerAFib.setAdapter(adapterAFib);
spinnerAFib.setOnItemSelectedListener(this);
//spinner for family health --> Hypertension
Spinner spinnerHypertension = findViewById(R.id.HBPSpinSelect);
ArrayAdapter<CharSequence> adapterHypertension =
ArrayAdapter.createFromResource(this, R.array.YN,
simple_spinner_item);
adapterHypertension.setDropDownViewResource
(android.R.layout.simple_spinner_dropdown_item);
spinnerHypertension.setAdapter(adapterHypertension);
spinnerHypertension.setOnItemSelectedListener(this);
//spinner for family health --> Hypertension
Spinner spinnerFamilialCVD = findViewById(R.id.familialCVDSpin);
ArrayAdapter<CharSequence> adapterFamilialCVD =
ArrayAdapter.createFromResource(this, R.array.YN,
simple_spinner_item);
adapterFamilialCVD.setDropDownViewResource
(android.R.layout.simple_spinner_dropdown_item);
spinnerFamilialCVD.setAdapter(adapterFamilialCVD);
spinnerFamilialCVD.setOnItemSelectedListener(this);
//declaring button
final Button BtnSave = findViewById(R.id.btnSaveNsend);
BtnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.ageEnter:
EditText enterAge = findViewById(R.id.ageEnter);
ageStr = enterAge.getText().toString();
age = Integer.valueOf(ageStr);
break;
case R.id.sysBPEnter:
EditText enterSys = findViewById(R.id.sysBPEnter);
sysBPStr = enterSys.getText().toString();
sysBPval = Integer.valueOf(sysBPStr);
break;
case R.id.diaBPEnter:
EditText enterDia = findViewById(R.id.diaBPEnter);
diaBPStr = enterDia.getText().toString();
diaBPval = Integer.valueOf(diaBPStr);
break;
case R.id.tcEnter:
EditText enterTC = findViewById(R.id.tcEnter);
tcStr = enterTC.getText().toString();
tcVal = Integer.valueOf(tcStr);
break;
case R.id.hdlEnter:
EditText enterHDL = findViewById(R.id.hdlEnter);
hdlStr = enterHDL.getText().toString();
hdlVal = Integer.valueOf(hdlStr);
break;
case R.id.ldlEnter:
EditText enterLDL = findViewById(R.id.ldlEnter);
ldlStr = enterLDL.getText().toString();
ldlVal = Integer.valueOf(ldlStr);
}
if (ethnicityChk == 1){
Intent RiskCalc1 = new
Intent(getApplicationContext(),displayLinRiskResult.class);
startActivity(RiskCalc1);
} else if (ethnicityChk == 2){
Intent RiskCalc2 = new
Intent(getApplicationContext(),displayDiscrimRiskResult.class);
startActivity(RiskCalc2);
}
}
});
}
@Override
public void onItemSelected(AdapterView<?>
adapterView, View view, int i, long l) {
switch(adapterView.getId()){
case R.id.sexSelect:
String sexStr = adapterView.getSelectedItem().toString();
if (sexStr.equalsIgnoreCase("female")){
sex = 1;
}
else if (sexStr.equalsIgnoreCase("male")){
sex = 0;
}
//Toast.makeText(adapterView.getContext(), sex,
Toast.LENGTH_SHORT).show();
break;
case R.id.marriedSelect:
String marriedStr = adapterView.getSelectedItem().toString();
if (marriedStr.equalsIgnoreCase("YES")){
married = 1;
}
else if (marriedStr.equalsIgnoreCase("NO")){
married = 0;
}
//Toast.makeText(adapterView.getContext(), married,
Toast.LENGTH_SHORT).show();
break;
case R.id.smokerSelect:
String smokerStr = adapterView.getSelectedItem().toString();
if (ethnicity.equalsIgnoreCase("Afro-Caribbean"))
{if (smokerStr.equalsIgnoreCase("Smoker")){
smoker = 1;
}
else if (smokerStr.equalsIgnoreCase("Non-smoker")){
smoker = 0;
} }
else if (ethnicity.equalsIgnoreCase("Mixed-Caribbean")){
{if (smokerStr.equalsIgnoreCase("Smoker")){
smoker = 0;
}
else if (smokerStr.equalsIgnoreCase("Ex-smoker")){
smoker = 1;
} }}
// Toast.makeText(adapterView.getContext(), smokerStr,
Toast.LENGTH_SHORT);
break;
case R.id.ethnicitySelect:
ethnicity = (String) adapterView.getSelectedItem();
if (ethnicity.equals("Afro-Caribbean")||
(ethnicity.equals("Indo-Caribbean"))){
ethnicityChk = 1;
}
else if (ethnicity.equals("Mixed-Caribbean")){
ethnicityChk = 2;
}
//Toast.makeText(adapterView.getContext(), ethnicityStr,
Toast.LENGTH_SHORT);
break;
case R.id.EduLevelSpin:
educationStr = (String) adapterView.getSelectedItem();
//Toast.makeText(adapterView.getContext(),education,
Toast.LENGTH_SHORT);
if (educationStr.equalsIgnoreCase("Secondary")){
educationSec = 1;
educationTert = 0;
education = 1;
}
else if (educationStr.equalsIgnoreCase("Tertiary")){
educationSec = 1;
educationTert = 1;
education = 1;
}
else {
education = 1;
educationSec = 0;
educationTert = 0;
}
break;
case R.id.highCholesterolSelect:
String highCholesterolStr = (String)
adapterView.getSelectedItem();
if (highCholesterolStr.equalsIgnoreCase("YES")){
highCholesterol = 1;
}
else if (highCholesterolStr.equalsIgnoreCase("NO")){
highCholesterol = 0;
}
//Toast.makeText(adapterView.getContext(),
highCholesterolStr,Toast.LENGTH_SHORT);
break;
case R.id.atrialFibrillationSelect:
String AfibStr = (String) adapterView.getSelectedItem();
if (AfibStr.equalsIgnoreCase("YES")){
atrialFibrillation = 1;
}
else if (AfibStr.equalsIgnoreCase("NO")){
atrialFibrillation = 0;
}
// Toast.makeText(adapterView.getContext(),
AfibStr,Toast.LENGTH_SHORT);
break;
case R.id.HBPSpinSelect:
String HBPstr = (String) adapterView.getSelectedItem();
if (HBPstr.equalsIgnoreCase("YES")){
hypertension = 1;
}
else if (HBPstr.equalsIgnoreCase("NO")){
hypertension = 0;
}
//Toast.makeText(adapterView.getContext(),
HBPstring,Toast.LENGTH_SHORT);
break;
case R.id.familialCVDSpin:
String famCVDStr = (String) adapterView.getSelectedItem();
if (famCVDStr.equalsIgnoreCase("YES")){
familialCVD = 1;
}
else if (famCVDStr.equalsIgnoreCase("NO")){
familialCVD = 0;
}
//Toast.makeText(adapterView.getContext(),
famCVDString,Toast.LENGTH_SHORT);
break;
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
这是用于输出结果的类:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_lin_risk);
TextView RiskViewLinRisk = findViewById(R.id.RiskViewLinRisk);
float LinRisk = (float) ((-16.13) + (0.119 * age) - (1.333 * sex)
+ (1.502 * married) + (2.619 * smoker) - (0.555 * (tcVal /
hdlVal)) + (0.026 *ldlVal) + (1.952 * highCholesterol) + (2.867
* atrialFibrillation) + (4.272 * hypertension) + (1.957 *
familialCVD));
String LinRiskStr = Float.toString(LinRisk);
RiskViewLinRisk.setText(LinRiskStr);
}
答案 0 :(得分:0)
只是提供比注释中更多的上下文,Java中的双除可以返回NaN
,它表示“不是数字”。将0.0除以0.0时会发生这种情况,但是如果取负数的平方根,也会发生这种情况。
因为Java为NaN实现了IEEE标准,所以它保证NaN永远不会等于其自身。实际上,唯一返回true的比较是NaN != NaN
。有一个非常著名的难题:
float x = //...
if (x != x)
System.out.println("Foo");
问题是“将x
初始化为可确保Foo被打印的值”。答案是Float.NaN
,因为NaN不等于其自身。另外,这是唯一可以起作用的值。 Java中的所有其他值都不能解决这个难题。
由于这个原因,一个解决方案花费了很多时间来确定数字是否为NaN为:
public boolean isNan(float x) {
return x != x;
}
(自Java 8起,标准库中存在一种方法来验证数字是否为NaN)
您可以使用它来检查您正在执行的除法结果,并在不需要时避免显示NaN。
要在单击按钮后显示值,必须再次运行计算并显示它。我建议将其提取为一种方法:
public float calculateLinRisk() {
return (float) ((-16.13) + (0.119 * age) - (1.333 * sex)
+ (1.502 * married) + (2.619 * smoker) - (0.555 * (tcVal /
hdlVal)) + (0.026 *ldlVal) + (1.952 * highCholesterol) + (2.867
* atrialFibrillation) + (4.272 * hypertension) + (1.957 *
familialCVD));
}
public void displayCurrentLinRisk() {
// This can also be a field in the main activity to
// avoid multiple calls to findViewById
TextView RiskViewLinRisk = findViewById(R.id.RiskViewLinRisk);
float LinRisk = calculateLinRisk()
String LinRiskStr = Float.toString(LinRisk);
RiskViewLinRisk.setText(LinRiskStr);
}
onCreate
变为:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_lin_risk);
displayCurrentLinRisk();
}
然后您可以在点击侦听器的末尾使用它
BtnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ...
displayCurrentLinRisk();
}
}