1

Нужно сравнить следующие пары чисел с точностью до 4-х значащих цифр.

  1. 1134 и 1132
  2. 9933 и 9932
  3. 11344 и 11342
  4. 99343 и 99342.

Соответственно, в первых двух случаях числа получаются неравными, а в последних - равными. Пробовал ввести заранее eps=0.001, и сравнивать его с относительными погрешностями, но не все тесты проходят. Также выяснил, что первая значащая цифра влияет на порядок числа. Как проделать это решение чисто математически, чтобы потом уже написать на любом языке?

2 Answers2

0

Я бы делал так:

  1. Ищем максимальное 10^n, такое, что оно меньше данного числа.
  2. Делим найденное число на 1000.
  3. Сравниваем результаты деления чисел на свои 10^n.

Примеры на ЯП

C++

#include <iostream>
#include <cmath>

using namespace std;

int get_d(int n){ return pow(10, int(log10(n)))/1000; }

bool is_equal(int n1, int n2){ return n1/get_d(n1) == n2/get_d(n2); }

int main(){ int n1, n2;

n1 = 99344;
n2 = 99346;

cout &lt;&lt; is_equal(n1, n2);

return 0;

}

n1tr0xs
  • 11,944
  • Почему делим на 1000? – Алексей Гросс Mar 11 '21 at 14:15
  • @АлексейГросс нужно 4 знака точности, а 10^4 = 10000. а мы делим на степень меньше т.к. ищем максимальное меньше. Если бы искали минимальное больше, то делили бы на 10000. На самом деле можно просто pow(10, int(log10(n)-3)) написать. – n1tr0xs Mar 11 '21 at 18:06
0

На питоне вообще в строковом виде проще решить:

def compare_n(a, b, n):
    return str(a)[:n] == str(b)[:n]

assert(not compare_n(1134, 1132, 4)) assert(not compare_n(9933, 9932, 4)) assert(compare_n(11344, 11342, 4)) assert(compare_n(99343, 99342, 4))

Но можно и математически:

import math

def cut_n(x, n): ix = int(math.log10(x)) + 1 return x // math.pow(10, ix - n if n < ix else 0)

def compare_n(a, b, n): return cut_n(a, n) == cut_n(b, n)

assert(not compare_n(1134, 1132, 4)) assert(not compare_n(9933, 9932, 4)) assert(compare_n(11344, 11342, 4)) assert(compare_n(99343, 99342, 4))

CrazyElf
  • 71,194
  • под математическим решением я подразумевал решение на бумаге – Алексей Гросс Mar 11 '21 at 12:32
  • на маленьких числах алгоритм не работает. к примеру, если взять -1.009e-7 и -1.008e-7 – Алексей Гросс Mar 11 '21 at 12:51
  • 1
    У вас не получится решить эту задачу, если вы будете использовать числа с плавающей запятой (float, double) - из-за перевода десятичных дробей в двоичные и обратно. Не все десятичные дроби можно представить в виде конечных двоичных дробей.

    Используйте арифметику с фиксированной запятой.

    – gbg Mar 11 '21 at 13:19
  • И как это сделать? – Алексей Гросс Mar 11 '21 at 13:53
  • И еще вопрос: как учесть то, что первая значащая цифра влияет на порядок числа? – Алексей Гросс Mar 11 '21 at 14:12