几天来我一直在尝试弄清楚为什么我的应用程序没有得到正确的输出。 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);
}
最佳答案
只是为了提供比注释更多的上下文,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();
}
}
关于android - 找不到为什么输出到 TextView 是 NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55487714/