2013-08-27 6 views
1

Я пытаюсь написать простой калькулятор на C#, где пользователь вводит процент веса и веса тела, и программа сообщает им свою массу тела. Когда отладка всегда кажется, что их скудная масса тела так же, как их вес ведет меня верить, что getBodyfatAmount возвращается 0.Метод Возвращение нуля в C#

namespace Fitness_Calcualtors 
{ 
    public partial class Lean_Body_Mass : PhoneApplicationPage 
    { 
     int bodyWeight, bodyFatPercentage, leanBodyMass, bodyFatAmount; 

     public Lean_Body_Mass() 
     { 
      InitializeComponent(); 
     } 

     private int getBodyfatAmount() 
     { 
      bodyFatAmount = ((bodyFatPercentage/100) * bodyWeight); 
      return bodyFatAmount; 
     } 

     private void convertInput() 
     { 
      bodyWeight = Convert.ToInt32(bodyweightTextBox.Text); 
      bodyFatPercentage = Convert.ToInt32(bodyFatTextBox.Text); 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
       if (kilogramsRadioButton.IsChecked ==true) 
       { 
        convertInput(); 
        getBodyfatAmount(); 

        leanBodyMass = (bodyWeight - bodyFatAmount); 
        resultTextBox.Text = leanBodyMass.ToString() + " Kilos"; 
       } 
       else if (poundsRadioButton.IsChecked == true) 
       { 
        convertInput(); 
        getBodyfatAmount(); 

        leanBodyMass = (bodyWeight - bodyFatAmount); 
        resultTextBox.Text = leanBodyMass.ToString() + " Lbs"; 
       } 
     } 
    } 
} 
+1

Какие значения, введенные в 'bodyweightTextBox' и 'bodyFatTextBox', когда' getBodyfatAmount() 'возвращает' 0'? –

+2

Вы должны подумать об этом: 'int bodyWeight, bodyFatPercentage, leanBodyMass, bodyFatAmount;' doubles вместо ints – DGibbs

+0

Я предполагаю, что, поскольку вы делите int, который, вероятно, меньше 100, когда он усекает десятичную, он уходит 0. попробуйте изменить все свои переменные на двойной – jonhopkins

ответ

4

Проблема заключается в том, что вы выполняете целочисленное деление в этой строке:

((bodyFatPercentage/100) * bodyWeight); 

Потому что (bodyFatPercentage/100) меньше 1, он автоматически усекается до 0, и поэтому вся функция возвращает 0.

Вы могли бы вместо этого использовать:

(int)((bodyFatPercentage/100.0) * bodyWeight); 

Альтернативы включают

(int)Math.Round((bodyFatPercentage/100.0) * bodyWeight); 
bodyFatPercentage * bodyWeight/100 

или просто возвращает значение с плавающей точкой.

Лично я возвращаю значение с плавающей запятой. Как общее правило, не отдавайте точность, пока вам не нужно ее отображать (и если вы хотите менее точный дисплей). В противном случае вы можете получить ошибки округления округления, что, по сути, произошло здесь.

+0

, это может не помочь, так как левый тип определяет тип оператора IIRC. – eFloh

+1

Метод возвращает 'int', хотя точка, которую вы сделали для целочисленного деления, верна, но это не решит проблему, возвращаемый тип метода должен быть типом, поддерживающим числа с плавающей запятой. – Habib

+0

Нет, будет выполнено расширение преобразования. Левый тип не определяет его, что определяет, какой тип имеет больше данных. –

2

Возможно, ваши ценности слишком малы, и результаты, как 0.something и int не может содержать . (десятичный), содержащее значение, поэтому он округляет значение ZERO. Я предлагаю вам использовать double для возврата значения.

1

Предполагая, что телоFatPercentage имеет значение от 0 до 100, (bodyFatPercentage/100) вернет 0. Почему? Потому что вы делите целые числа. Измените свой код, чтобы использовать двойные значения, и вы на правильном пути.

Если ваш результат типа int, вам может потребоваться бросить или лучше Math.Round результат назад к int.

+0

Полезный совет: установите точку останова на свой метод (нажмите на левую панель или нажмите F9) и наведите указатель мыши на переменные. Вы также можете выбрать целое выражение и навести указатель мыши или нажать SHIFT + F9, чтобы увидеть его значение. – eFloh

0

Во-первых, вам нужно пройти через отладчик, чтобы подтвердить точный источник проблемы.

Однако, я ожидаю, что проблема связана с округлением. При работе с разделением лучше всего использовать тип, который поддерживает десятичные знаки.

Попробуйте это:

bodyFatAmount = (int)((bodyFatPercentage/100f) * bodyWeight); 

В принципе, bodyFatPercentage/100 всегда будет приводить к 0.xx (математически), но потому, что вы используете int типы (которые не поддерживают знаков после запятой) будет округлять значение для 0 , используя 100f, вы объявляете один из типов как float (который поддерживает десятичные знаки), таким образом результат будет сохранять десятичную точность (0.xx), тогда это будет умножено на bodyWeight и снова будет иметь значение поплавка (сохранение десятичной места), наконец, ваш общий результат можно отбросить на int.Это будет снова сделать раунд, но тогда вы будете иметь более точный результат, например, (int)63.22 ->63


На стороне записки, это очень странно для функций, чтобы установить глобальные переменные, как, что, а затем вернуть значение. Просто мои мысли мысли ...

2

Все остальные дадут вам программное решение для литья на поплавок или двойное первое, но есть еще одно решение из 3-го класса математического класса. Умножение и деление транзитивны.

bodyFatAmount = ((bodyFatPercentage * bodyWeight)/100); 

Теперь умножение первого вы получите число больше 100 и не получить проблему усечения после того, как вы разделите это все равно даст вам правильное процентное значение.

1

Попробуйте изменить ниже, ваши проблемы связаны с выполнением нецелочисленных математических вычислений с целыми числами. Я также прибрал часть кода, чтобы быть более удобным для чтения и ближе к Microsoft стандартов кодирования, удалены избыточные скобки, удаляются излишние приватные переменные и т.д .:

public partial class LeanBodyMass : PhoneApplicationPage 
{ 
    private decimal bodyWeight; 
    private decimal bodyFatPercentage; 

    public LeanBodyMass() 
    { 
     InitializeComponent(); 
    } 

    private decimal GetBodyFatAmount() 
    { 
     return bodyFatPercentage/100m * bodyWeight; 
    } 

    private void ConvertInput() 
    { 
     bodyWeight = Convert.Decimal(bodyweightTextBox.Text); 
     bodyFatPercentage = Convert.Decimal(bodyFatTextBox.Text); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     this.ConvertInput(); 
     this.GetBodyFatAmount(); 

     decimal leanBodyMass = bodyWeight - bodyFatAmount; 

     if (kilogramsRadioButton.IsChecked ==true) 
     { 
      resultTextBox.Text = string.Format("{0} Kilos", leanBodyMass); 
     } 
     else if (poundsRadioButton.IsChecked == true) 
     { 
      resultTextBox.Text = string.Format("{0} Lbs", leanBodyMass); 
     } 
    } 
}