Как преобразовать double в int при преобразовании минут в секунды в java

#java

Вопрос:

Попытка преобразовать минуты в секунды с использованием двойных исходных данных,

так, например, 33,51 секунды (33 минуты 51 секунда) Как преобразовать это в int при преобразовании в seconeds только мой код на данный момент принял бы это, если бы для начала не было двойной точки, поэтому я использовал только ints, и, похоже, это работает, но когда у меня есть этот двойной, это не так, есть ли лучший подход к этому .

Вот мой код на данный момент

 public class Runner {  //fields setting up the variables  String MembershipID;  String name;  int time ;  //constructor1 filling in the details  public Runner(String Mem, String na, int ti) {  MembershipID = Mem;  name = na; //This  time = ti;    }   public String getMembershipID() {  return MembershipID;  }   public String getName() {  return name;  } //setting it up for the main method from the constructor fields above   public int getTime() {  int mins = time *60;      return mins;  }        public static void main(String[] args) { //initializing the membership name and time,  Runner a = new Runner("RF23", "George Formsby", 33); //Creating a new instance of  Runner, filling out the details from the sample data provided.  Runner b = new Runner("RG89", "Neil Innes", 32);  Runner c = new Runner("ST200", "Sandy Denny", 30); // With mem and na being  represented from my constructor  System.out.println("MembershipID is: "   a.getMembershipID());  System.out.println("Name is: "   a.getName());  System.out.println("Time in seconds: "   a.getTime());  System.out.println("MembershipID is: "   b.getMembershipID());  System.out.println("Name is: "   b.getName());  System.out.println("Time is: "   b.getTime());  System.out.println("MembershipID is: "   c.getMembershipID());  System.out.println("Name is: "   c.getName());  System.out.println("Time is: "   c.getTime());    }          }  

Комментарии:

1. Вы уверены , что 33.51 это должно быть 33 минуты и 51 секунда? Что было бы 33.70 в этом случае?

2. 33.51 должно быть около 33 минут и 30,6 секунды.

3. Извините, если я неправильно понял ваш вопрос, но не могли бы вы просто рассчитать все это, если 33,51% 1-секунды, а математический раунд(33,51/1) — минуты? Конечно, конечно, 33.51 не должны составлять 33 минуты и 30 секунд

4. плохая идея использовать двойник для десятичной арифметики. Вы можете представить с помощью int как часы*100 минут, а затем преобразовать обратно

5. Это похоже на использование неправильного типа данных для задания. 33 минуты и 51 секунда никогда не должны быть представлены двойником 33.51 . Вы могли бы использовать Duration , но если вы хотите придерживаться int , он должен представлять количество секунд. В вашем примере это будет 2031 год ( 33 * 60 51 ).

Ответ №1:

Кажется, достаточно простая математика.

Преобразуйте минуты секунды всего в секунды

 int minutes = ...; int seconds = ...; int totalSeconds = minutes * 60   seconds;  

Преобразуйте минуты (в двойном размере) в секунды

 double time = 12.33; int seconds = (int) (0.5   time * 60);  

Пояснение: при округлении до an int java отключает десятичные части. Мы хотим округлить до ближайшей секунды, что может быть тривиально выполнено (для положительных чисел!) добавив к нему 0,5, а затем приведя int к.

ПРИМЕЧАНИЕ: Смотрите примечание ниже!

Преобразуйте секунды (как int) в минуты (как double)

 int totalSeconds = ....; double time = time / 60.0;  

Пояснение: В java синтаксическая конструкция x / y считается «целочисленным делением», если x и y оба являются целочисленными типами данных ( byte , short , int , long , или char ). Это считается «делением с плавающей запятой», если x или y являются типом с плавающей запятой ( float или double ). целочисленное деление будет отсекать десятичные цифры (поэтому оно округляется для положительных результатов и округляется для отрицательных результатов). Так 90 / 2 , например , решает 1 К. Нет 1.5 . С другой стороны, 90 / 2.0 решает 1.5 , потому что по крайней мере одно из двух чисел является двойным ( 2.0 является двойной константой, 2 является константой int). Следовательно, почему мы делим на 60.0 и не 60 .

NB: Важная вещь, о которой нужно подумать: ТОЧНОСТЬ.

Компьютеры не являются волшебными и double точно определены как состоящие ровно из 64 бит.

Вы не можете хранить один из бесконечной последовательности вариантов в ограниченном пространстве хранения, поэтому компьютеры не могут идеально хранить числа. 64-разрядное пространство для хранения данных может предоставить вам самые 2^64 разные «опции». Если в хранилище хранится число, это означает 2^64 , что там может храниться не более чисел, и поэтому все остальные числа просто не могут быть им представлены. Кто-то должен выйти и определить, какие числа являются «благословенными» — способными храниться. Затем кто-то должен определить, что произойдет, если вы попытаетесь сохранить в них не благословенное число.

Для целочисленных типов данных это просто: int (32-разрядные) могут хранить 2^32 числа. Какие числа благословенны? Просто -2^31 чтобы 2^31 -1 . Когда вы пытаетесь сохранить что-то выше или ниже этого, числа просто описывают круг:

 int reallyLarge = Integer.MAX_VALUE; // this is 2^31-1. int surelyThisIsEvenLarger = reallyLarge   1;  

На самом деле, surelyThisIsEvenLarger это отрицательное число вместо этого. Он петлял вокруг.

Ибо double и float это намного сложнее. Даже между просто 0 и 1 есть бесконечные числа! Благословенные числа выбираются путем более или менее метания дротиков в числовую линию, фокусируя около половины дротиков вблизи 1.0 , при этом все меньше и меньше дротиков попадает в числовую линию по мере удаления от 1,0. В конечном счете, примерно 2^52 на «расстоянии» между любыми 2 дротиками больше, чем 1.0 даже.

Это немного похоже на то, как мы, люди, это делаем: мы вообще не можем «представлять» 1, разделенное на 3. 0.333333.... это никогда не кончается.

Что еще хуже, компьютеры считают в двоичном, а не десятичном формате. Итак, там , где мы, люди, можем, например, сделать «1, деленное на 10» (то 0.1 есть, это благословенное число в системе «человек записывает его десятичным числом на листе бумаги, в котором есть место примерно для 10 цифр»), компьютеры тоже не могут этого сделать.

Таким образом, большинство значений «возьмите это количество секунд и превратите их в двойное» на самом деле не благословлены, поэтому важно понимать, что происходит, когда вы пытаетесь сделать двойное, которое не благословлено: компьютер округлит его до ближайшего благословенного числа. Вы не можете запросить ошибку (сумму, на которую она округлена), или попросить ее не делать этого; double во всяком случае, не с помощью.

Если вы сделаете достаточно математических вычислений для них, эти ошибки усугубятся и в конечном итоге будут совершенно неправильными. Это одна из многих причин, по которым вы определенно никогда, никогда не должны использовать double для хранения денежных ценностей. Для мониторинга гонок вы сталкиваетесь с аналогичной ситуацией здесь, лучше не использовать их. Лучше выбрать атомную единицу и хранить в них. Например, почему бы не хранить в миллисе? Текущий рекорд самой быстрой мили-3:43.13. В «миллисе» это становится long fastestMile = 223130; — нет необходимости вовлекать этих мерзких двойников с их странным округлым поведением.