Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Проблема с числами с плавающей точкой. (https://javascript.ru/forum/misc/77093-problema-s-chislami-s-plavayushhejj-tochkojj.html)

friosound 24.03.2019 09:29

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

ссылка на условие в оригинале

На вводе имеется Float-число с четырьмя знаками после точки. Необходимо создать массив и вывести в консоль последовательно убывающую геометрическую прогрессию этого числа длинной в сто элементов. При этом каждое число должно отборажаться с также с четырьмя знаками после точки.

Пример ввода и вывода:

Ввод: 200.0000

Вывод:

N[0] = 200.0000
N[1] = 100.0000
N[2] = 50.0000
N[3] = 25.0000
N[4] = 12.5000
...бла бла и так до N[99]

Я если честно опробовал уже тучу разных вариантов , и всё равно при проверке получаю 5 процентов неверного вывода. Подозреваю , что проблема при неправильном округлении метода .toFixed(), но как её побороть ума не приложу .. помогите плс, может кто хорошо в этой теме шарит.

Вот несколько вариантов моих решений:

var input = require('fs').readFileSync('/dev/stdin', 'utf8');
var lines = input.split('\n');

let x = parseFloat(lines[0]).toFixed(4);
let N=[],i,temp=0;
N[0] = x;
console.log(`N[${0}] = ${x}`);
for (i = 1; i < 100; i++){
  temp = (Math.floor((N[i-1])*10000)/10000);
  N[i] = temp/2;
  let string = String(Math.floor((N[i])*10000)/10000);
  let float = parseFloat(string).toFixed(4);
  console.log(`N[${i}] = ${float}`);
  }


------
let x = parseFloat(lines[0]);
let N=[],i,temp=0;
console.log(`N[0] = ${x.toFixed(4)}`);
for (i=1; i<100; i++) {
  N[i] = (x*10000/10000) / (Math.pow(2 ,i));
  console.log(`N[${i}] = ${parseFloat(N[i]).toFixed(4)}`);
}

-----
let x = parseFloat(lines[0]);
let N=[];
N[0] = x;
for (let i=1; i<100; i++) {
  N[i] = ((x*10000) / (Math.pow(2 ,i)) / 10000);
  let temp = String(N[i].toFixed(5));
  let compare = temp.substring(6);
  if (compare === '5'&& temp>0.00005) {
    N[i] = N[i].toFixed(4) - 0.0001;
  }
}
for (let i=0; i<100; i++) {
  console.log(`N[${i}] = ${(N[i].toFixed(4))}`);
}

рони 24.03.2019 09:58

Цитата:

Сообщение от friosound
получаю 5 процентов неверного вывода

что не так, пример?
<script>
    var n = 200.0000;
    n *= 10000;
    for (var i = 0; i < 100; i++) {
        document.write(i + " - " + (n/10000).toFixed(4) +"<br>");
        n /=2;
    }
    </script>

friosound 24.03.2019 10:16

8 - 0.7813 - в данном конкретном выводе вот тут 0.7812 верно :)

рони 24.03.2019 10:57

Цитата:

Сообщение от friosound
тут 0.7812 верно

почему? может вам не оругление нужно?

почты прочую обяза ниже. 24.03.2019 12:14

const n = 200.0000
const length = 100

const N = []
for (let i = 0; i < length; i++) {
	N[i] = Math.floor((i ? N[i - 1] / 2 : n) * 10000) / 10000 // урезание
}

N.forEach((n, i) => {
	console.log('N[%d] = %s', i, n.toFixed(4))
})
Цитата:

i ? N[i - 1] / 2 : n

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

friosound 24.03.2019 12:50

Вложений: 1
https://javascript.ru/forum/attachme...d=155342123 0

рони 24.03.2019 14:41

friosound,
lires???

friosound 24.03.2019 14:59

нет , нет ..там всё верно написано. Это у меня скриншот почему-то в паинте так коряво отображает.

почты прочую обяза ниже. 24.03.2019 15:12

Если задача предполагает округление, тогда мне тоже непонятно, почему элемент с индексом 8 не засчитан:

Код:

i                        | 8                | 11

 правильный (✔)                | 0.7812        | 0.0977
 полный                        | 0.78125        | 0.09765625
 округленный                | 0.7813        | 0.0977 ✔
 урезанный                | 0.7812 ✔        | 0.0976


То есть, в индексе 8 предполагается урезание, а уже в индексе 11 - округление.
При этом, при решении через округлении только индекс 8 неверен.

friosound 25.03.2019 06:46

проблема в том , что это - автоматическая система тестирования. Имеется непонятно какое количество валидных выводов , которые , как я понимаю сравниваются с моими при отправке кода.

Что касается выводов - не факт , что не засчитывает именно этот случай. Я сравниваю вывод каждого решения , запуская его в node и потом сравниваю с ''якобы'' валидными вариантами вот здесь:

https://www.udebug.com/URI/1178 - ссылка на этот ресурс висит в условии задачи , как рекомендуемая для проверки.

Моё третье решение предполагает принудительное урезание, и вот тогда на Udebug часть выводов у меня идентичны , но при попытке сравнить вывод числа 100000000000000000000.0000 - уже один элемент меньше , т.е. предполагается округление.

Что интересно, смотрел решения на java или C , и там у ребят проходят проверку варианты с округлением т.е. 8 элемент 0.7813 при числе 200.0000


Часовой пояс GMT +3, время: 01:27.