Как получить дробное число при вычислении
Я в принципе знаю ответ, но помощь не помешает. Мне например нужно записать c=1/7. Почему надо в этом типе обязательно писать c=1.0/7.0?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как получить при делении дробное число?
Я встретился с такой проблемой, я не могу поделить в программе меньшое число на большое. Что я уже.
Как получить случайное дробное число в заданном диапазоне
Как получить случайное число с плавающей запятой. Так не получается: Dim cRandom As Random Dim.
Получить случайное дробное число
Вот код var randomTicket = helper.getRandomInt(0, g_Totalcost); Там идут числа к примеру от.
Получить случайное дробное число
в C# нет функции, которая получает случайное дробное число. Я попробовал написать самостоятельно.
При делении чисел пропадает дробная часть
Я делю два числа друг на друга, например 1 / 2 и ожидаю получить в результате 0.5 , так как присваиваю результат переменной с плавающей точкой, но получаю 0 . Вот код:
#include int main() < double d = 1 / 2; std::cout
В чём может быть проблема?
Отслеживать
задан 4 окт 2017 в 21:06
29k 14 14 золотых знаков 61 61 серебряный знак 119 119 бронзовых знаков
Связанный вопрос: Зачем при записи чисел в конце добавляют .0?
5 окт 2017 в 9:46
@zed о. Я даже там в комментариях отметился давненько.
5 окт 2017 в 12:33
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Дело в том, что в C++, а равно как и в C, C#, Java и многих других языках деление целых чисел даёт исключительно целый же результат, т.е. дробная часть просто отбрасывается.
Стандарт языка буквально так это и говорит [expl.mul]:
For integral operands the / operator yields the algebraic quotient with any fractional part discarded;
Подобное поведение обусловлено в первую очередь производительность, т.к. целочисленная арифметика обычно работает быстрее арифметики с плавающей точкой.
То, что результат деления целых чисел присваивается переменной с плавающей точкой не влияет на само деление, т.к. присваивание выполняется уже после факта деления. И мы просто инициализируем вещественную переменную d целым значением 0 , которое никак не даст нам чего-то с ненулевой дробной частью, например, ожидаемых 0.5 .
Чтобы всё-таки добиться желаемого результата нужно производить вещественное деление. Для этого достаточно хотя бы один из операндов привести к вещественному типу. Сделать это можно разными способами. Если используется константа, то достаточно дописать в конце неё точку, например:
double d = 1 / 2.;
double d = 1. / 2;
Это выглядит минималистично, но иногда несколько странно, т.к. в математике подобная запись не используется. Для большей наглядности стоит добавить .0 , получим:
double d = 1.0 / 2;
Если вместо явного числового литерала используется именованная целочисленная переменная, или функция, возвращающая целый тип, то добавлением точки с нулём проблему уже не решить, и нужно выполнять иное приведение типа, т.е. делать static_cast :
int one = 1; int two() < return 2; >double d = static_cast(one) / two();
Но можно использовать и умножение (или деление) любого операнда на 1.0 , что так же преобразует результат, который будет выступать операндом последующего деления, к вещественному типу:
double d = (one * 1.0) / two();
Альтернативным вариантом может быть прибавка (или вычитание) вещественного нуля:
double d = (one + 0.0) / two();
Однако, вариант со static_cast будет более правильным, т.к. такие преобразования всегда легче находить в тексте программы, нежели обычные плавающие константы.
Ну и конечно же, если речь идёт о переменных или функциях, то можно просто изменить их тип:
double one = 1; double two() < return 2; >double d = one / two();
В такой ситуации надо не забывать, что использование one и two в других контекстах так же может давать иные результаты, что были раньше. Поэтому задачу всё же лучше локализовать, и не делать всё поголовно в программе вещественного типа, если это требуется только в некоторых частных случаях.
Алгоритм деления 2W-разрядных чисел с использованием операций с числами разрядностью W
На примере 32-битных целых чисел рассматривается масштабируемый алгоритм деления, использующий числа с двукратно меньшей (16 бит) разрядностью. Для иллюстрации работоспособности алгоритма приведен код тестового приложения на языке С++.
Описание алгоритма
Представим некоторое -битное число в виде:
где , - старшая и младшая части -битных компонент числа, соответственно.
Тогда деление двух чисел, и , можно записать в виде дроби:
Заметим, что если , то результат деления - некоторое -битное число. Ограничимся этим случаем. Для в примере ниже на С++ реализован алгоритм деления "широкого" числа на "узкое", основанный на представлении делимого в виде произведения частного и делителя плюс слагаемого-остатка :
Считаем далее, что , иначе - результат деления равен нулю. Представим число в виде:
Здесь - целая часть от деления, а - остаток от деления на .
Пренебрежем слагаемым , чтобы получить нижнюю оценку результата деления плюс дополнительно упростить формулу:
Выделим слагаемое в качестве главной компоненты:
Сделаем замену переменных Дело в том, что "тяжелые" случаи соответствуют параметру достаточно большому, поэтому введенный параметр "дельта" при этом будет мал и формула быстрее приведет к результату:
В числителе и знаменателе дроби стоят "широкие" числа (разрядностью ). Так как допускается использовать алгоритм деления широкого числа на узкое, то добьемся "узости" числа в знаменателе, вынеся множитель за скобки и выполняя деление последовательно:
Таким образом, "широкий" числитель последовательно делим на "узкие" знаменатели. Первый знаменатель иногда может равняться множителю , что необходимо отслеживать в алгоритме: в регистрах ЦПУ число фактически обнулится и возникнет исключение. Альтернативно, можно заранее вычесть единицу и не заботиться о граничных условиях, так как для данного алгоритма . Аналогично поступаем с переменной , что в итоге даст окончательный вариант:
Численный эксперимент показал, что достаточно одной вышеописанной итерации. Физически это объясняется тем, что алгоритм разработан специально для , что приводит к достаточно большому числу в знаменателе и сравнительно небольшому частному. Однако, для получения окончательного результата требуется "fine tuning" --- последовательное прибавление или вычитание единицы в зависимости от текущей ошибки деления, что можно сделать в цикле и за одно получить остаток от деления. Для этого необходима реализация оператора умножения "широкого" числа на "узкое", при этом дополнительно следует отслеживать переполнение, в результате которого придется уменьшить частное на единицу.
Заметим, что предложенный алгоритм не привязан к типу чисел: целое, с плавающей точкой, в альтернативной системе счисления и т. п. Основа алгоритма предполагает возможность разделения произвольного числа на две половинки: старшую и младшую. Знаковые биты обрабатываются отдельной логикой, так, чтобы фактически обрабатывались числа без знака.
Пример реализации алгоритма деления на С++
#include #include #include #include #include #include #include #include #include using u64 = uint64_t; using i64 = int64_t; using u32 = uint32_t; using u16 = uint16_t; struct Quadrupole < u16 A; u16 B; u16 C; u16 D; >; struct Signess < int s1; int s2; >; static auto const seed = std::random_device<>(); /*** * Генератор случайных чисел. */ auto rollu16 = [urbg = std::mt19937, distr = std::uniform_int_distribution<>]() mutable -> u16 < return distr(urbg); >; static constexpr char DIGITS[10]; // High/Low структура 32-битного числа со знаком и флагом переполнения. // Для иллюстрации алгоритма деления двух U32 чисел реализованы основные // арифметические операторы, кроме умножения двух U32 чисел. // Если дополнительно реализовать полноценное умножение, то структура // позволяет себя масштабировать: реализовывать 128-битные числа, // 256-битные и т.д. struct U32 < static constexpr int mHalfWidth = (sizeof(u16) * CHAR_BIT) / 2; u16 mHigh = 0; u16 mLow = 0; int mSign = 0; int mOverflow = 0; /** * Оператор проверки на ненулевое значение. */ bool operator()() < return (mLow != 0) || (mHigh != 0) || (mOverflow != 0); >U32 operator+(U32 rhs) const < U32 res<>; U32 X = *this; if (X.mSign != 0 && rhs.mSign == 0) < X.mSign = 0; res = rhs - X; return res; >if (X.mSign == 0 && rhs.mSign != 0) < rhs.mSign = 0; res = X - rhs; return res; >res.mLow = X.mLow + rhs.mLow; const u16 c1 = res.mLow < std::min(X.mLow, rhs.mLow); res.mHigh = X.mHigh + rhs.mHigh; const int c2 = res.mHigh < std::min(X.mHigh, rhs.mHigh); auto tmp = res.mHigh; res.mHigh = tmp + c1; const int c3 = res.mHigh < std::min(tmp, c1); res.mOverflow = c2 || c3; if (X.mSign != 0 && rhs.mSign != 0) < res.mSign = 1; >return res; > U32 operator-(U32 rhs) const < U32 res<>; U32 X = *this; if (mSign != 0 && rhs.mSign == 0) < rhs.mSign = 1; res = rhs + X; return res; >if (mSign == 0 && rhs.mSign != 0) < rhs.mSign = 0; res = X + rhs; return res; >if (mSign != 0 && rhs.mSign != 0) < rhs.mSign = 0; X.mSign = 0; res = rhs - X; return res; >res.mLow = X.mLow - rhs.mLow; res.mHigh = X.mHigh - rhs.mHigh; const int c1 = X.mLow < rhs.mLow; if (c1 != 0) < res.mLow -= 1u; res.mLow += 1u; res.mHigh -= 1u; const int c2 = X.mHigh < (rhs.mHigh + 1u); if (c2 != 0) < res.mHigh = -res.mHigh - 1u; res.mLow = -res.mLow; res.mSign = 1; >> else if (X.mHigh < rhs.mHigh) < res.mHigh = (res.mLow != 0) ? -res.mHigh - 1u : -res.mHigh; res.mLow = -res.mLow; res.mSign = 1; >return res; > U32 mult16(u16 x, u16 y) const < constexpr u16 mask = (1u > mHalfWidth; auto y_high = y >> mHalfWidth; auto t1 = x_low * y_low; auto t = t1 >> mHalfWidth; auto t21 = x_low * y_high; auto q = t21 >> mHalfWidth; auto p = t21 & mask; auto t22 = x_high * y_low; auto s = t22 >> mHalfWidth; auto r = t22 & mask; auto t3 = x_high * y_high; U32 res<>; res.mLow = t1; auto div = (q + s) + ((p + r + t) >> mHalfWidth); auto mod = (t21 U32 operator*(u16 rhs) < U32 tmpB = mult16(mLow, rhs); U32 tmpA = mult16(mHigh, rhs); tmpA.mHigh = tmpA.mLow; tmpA.mLow = 0; tmpB = tmpB + tmpA; if (this->mSign != 0) < tmpB.mSign = 1; >return tmpB; > U32 operator/(u16 y) const < U32 rem = *this; auto iter1 = [&rem](u16 v) < U32 res<>; auto q0 = rem.mLow / v; auto r0 = rem.mLow % v; auto q1 = rem.mHigh / v; auto r1 = rem.mHigh % v; res.mLow = q0; res.mHigh = q1; rem.mLow = r0; rem.mHigh = r1; return res; >; auto iter2 = [&rem](u16 v) < U32 res<>; auto d = (1 u ; U32 result<>; result = result + iter1(y); result = result + iter2(y); if (this->mSign != 0) < result.mSign = 1; >return result; > U32& operator/=(u16 y) < *this = *this / y; return *this; >U32 operator/(const U32 other) const < U32 X = *this; U32 Y = other; constexpr U32 ZERO; constexpr U32 UNIT; constexpr U32 UNIT_NEG< .mHigh = 0, .mLow = 1, .mSign = 1, .mOverflow = 0>; if (mHigh < Y.mHigh) < return ZERO; >if (Y.mHigh == 0) < U32 res = X / Y.mLow; if (Y.mSign != 0) < res.mSign = res.mSign != 0 ? 0 : 1; >return res; > if (X.mSign != 0 && Y.mSign != 0) < X.mSign = 0; Y.mSign = 0; >bool make_sign_inverse = false; if ((X.mSign != 0 && Y.mSign == 0) || (X.mSign == 0 && Y.mSign != 0)) < X.mSign = 0; Y.mSign = 0; make_sign_inverse = true; >assert((Y.mHigh != 0) || (Y.mLow != 0)); const u16 Q = mHigh / Y.mHigh; const u16 R = mHigh % Y.mHigh; const u16 Delta = (1u ; W1.mHigh = R >= Q ? R - Q : Q - R; W1.mLow = 0; W1.mSign = R >= Q ? 0 : 1; W1 = W1 + DeltaQ; u16 C1 = Y.mHigh + 1u; C1 = C1 != 0 ? C1 : (1 u + Quotient; U32 N = Y * result.mLow; if (N.mOverflow != 0) < result.mLow -= 1; N = Y * result.mLow; >U32 Error = (result.mSign == 0) ? X - N : X + N; U32 More = Error - Y; bool do_inc = More.mSign == 0; bool do_dec = Error.mSign == 1; while (do_dec || do_inc) < result = result + (do_inc ? UNIT : (do_dec ? UNIT_NEG : ZERO)); if (do_dec) < Error = Error + Y; >if (do_inc) < Error = Error - Y; >More = Error - Y; do_inc = More.mSign == 0; do_dec = Error.mSign == 1; > if (make_sign_inverse) < result.mSign = result.mSign != 0 ? 0 : 1; >return result; > /** * Возвращает строковое представление числа. */ std::string value() const < std::string result<>; if (this->mOverflow != 0) < result = "Overflow"; return result; >U32 tmp = *this; constexpr int multiplier_mod10 = (1u if (mSign != 0 && (mHigh != 0 || mLow != 0)) < result.push_back('-'); >std::reverse(result.begin(), result.end()); return result.length() != 0 ? result : "0"; > >; bool test_div(U32 z1, U32 z2) < const U32 z3 = z1 / z2; i64 x = ((u64)z1.mHigh return is_ok; > void test_division_quick() < const std::listargs = < , , , , , , , , , , , , , , , >; auto make_test = [](const Quadrupole q) -> bool < return test_div(, ); >; bool is_ok = true; for (const auto& arg : args) < is_ok &= make_test(arg); >assert(is_ok); > void test_division_randomly(long long N) < auto make_test = [](const Quadrupole q, const Signess s) ->bool < return test_div(U32, U32); >; long long counter = 0; long long ext = 0; bool is_ok = true; while (true) < ++counter; const Quadrupole q; const Signess s; if (q.C == 0 && q.D == 0) < continue; >is_ok &= make_test(q, s); assert(is_ok); if (counter % (1ll if (ext >= N) < break; >> > int main(int argc, char* argv[]) < long long N = 10; if (argc >1) < N = std::atoi(argv[1]); std::cout < U32 x; std::cout < U32 x; std::cout std::cout
Выводы
Предложен и протестирован алгоритм деления чисел, состоящих из старшей и младшей половинок, масштабирующийся на произвольную разрядность кратно . Данный алгоритм в некотором смысле является вариантом "умного" деления в столбик: сначала вычисляется первое приближение, равное делению старших половинок числа, а затем - второе, равное скорректированному первому. Корректор равен последовательному делению некоторого широкого числа на два узких.
Предложенный алгоритм легко масштабируется на 128-битный вариант с использованием встроенной 64-битной арифметики. Однако, вариант с масштабированием, например, на 256-бит, требует реализации в структуре U128 полноценного умножения, что можно сделать, масштабируя реализованный оператор "половинчатого" умножения: U32 на u16. Также потребуется реализация оператора побитового сдвига. В конечном итоге, при реализации всех необходимых операторов можно реализовать шаблонную структуру с произвольной разрядностью , рекурсивно (делением пополам) спадающую в арифметику 64-битных встроенных чисел.
- длинная арифметика
- системы счисления
Как делить дробь на целое число
Соавтор(ы): David Jia. Дэвид Джиа — репетитор и основатель частной репетиторской компании LA Math Tutoring в Лос-Анджелесе, Калифорния. Имеет более 10 лет преподавательского опыта, работает с учащимися всех возрастов и классов над разными предметами, а также занимается конультированием по поступлению в колледж и подготовкой к SAT, ACT, ISEE и другим тестам. Набрав максимальные 800 баллов за SAT по математике и 690 — по английскому языку, получил стипендию Дикинсона в Университете Майами, который окончил со степенью бакалавра делового администрирования. Кроме того, был инструктором в обучающих онлайн-видео компаний, выпускающих учебники, таких как Larson Texts, Big Ideas Learning и Big Ideas Math.
Количество просмотров этой статьи: 220 690.
В этой статье:
Делить дроби на целые числа не так сложно, как кажется. Для этого целое число нужно представить в виде дроби, затем поменять в этой новой дроби местами числитель и знаменатель, а потом перемножить две имеющиеся дроби! Для примера мы используем 2/3 ÷ 4, деление осуществляется в несколько шагов, так что приступим.
Перепишите пример. Первым делом вам нужно записать дробь, затем знак деления, затем целое число. В нашем случае это выглядит так: 2/3 ÷ 4. [1] X Источник информации
Переведите целое число в дробь. Сделать это довольно просто. Запишите целое число в числитель, а 1 — в знаменатель. Получается дробь! В нашем примере 4 превращается в 4/1 (то же самое, что и 4). Теперь наш пример приобрел вид 2/3 ÷ 4/1. [2] X Источник информации
Деление дроби на дробь — это то же самое, что и умножение первой дроби на дробь, противоположную второй.
Запишите дробь, противоположную второй. Как это сделать? Все очень просто — поменяйте числитель и знаменатель местами. Надо найти дробь, противоположную 4/1? Меняем местами числитель и знаменатель, получаем 1/4. [3] X Источник информации
Теперь замените знак деления знаком умножения. Наш пример выглядит уже так: 2/3 x 1/4. [4] X Источник информации
- Числители: 2 x 1 = 2.
- Знаменатели: 3 x 4 = 12.
- 2/3 x 1/4 = 2/12
- 2 ÷ 2 = 1
- 12 ÷ 2 = 6
- Дробь 2/12 упрощается в 1/6. Это — искомый ответ.
- Если знаете английский язык, воспользуйтесь следующим мнемоническим правилом, которое поможет вам запомнить последовательность действий при делении дроби на целое число: «Dividing fractions is easy as pie, flip the second number and multiply!»
- Все, что нужно сделать: перевернуть числа и умножить.
- Если вы сокращаете до того, как умножать, вам, вероятно, не понадобится сокращать. В нашем примере числитель первой дроби (2) и знаменатель второй (4) оба делятся на 2, так что мы можем сразу их сократить, вместо того чтобы умножать 2/3 × 1/4. Так мы упростим пример до 1/3 × 1/2 и в итоге получим 1/6, избежав сокращений в конце.
- Если какая-то из дробей отрицательна, данный способ все равно можно использовать. Нужно лишь следить за знаками. Помните, если дробь отрицательная, то знак минус относится лишь к числителю.
- Сокращайте перед умножением, вместо того чтобы сокращать в конце.
- Не изменяйте дробь. Поменяйте знак деления на знак умножения. Представьте целое число в виде дроби, подставив в знаменатель единицу. Найдите обратное второй дроби. Вычислите результат. Упрощайте там, где это возможно.
Предупреждения
- Берите обратное только второй дроби, той, на которую делим. Первую (ту, которую делим) не меняйте. В нашем примере мы изменили 4/1 на 1/4, но оставили 2/3 как 2/3 (мы не меняли ее на 3/2).
Дополнительные статьи
найти квадратный корень числа вручную
найти среднее значение, моду и медиану
вычислить общее сопротивление цепи
вычесть дробь из целого числа
решать кубические уравнения
извлечь квадратный корень без калькулятора
найти множество значений функции
переводить из двоичной системы в десятичную
перевести миллилитры в граммы
умножить в столбик
проводить действия с дробями
вычислить вероятность
найти область определения и область значений функции
разделить целое число на десятичную дробь
- ↑http://www.mathsisfun.com/numbers/fractions-division-whole-numbers.html
- ↑http://www.math.com/school/subject1/lessons/S1U4L8DP.html
- ↑https://www.montereyinstitute.org/courses/DevelopmentalMath/TEXTGROUP-1-8_RESOURCE/U02_L2_T2_text_final.html
- ↑https://www.montereyinstitute.org/courses/DevelopmentalMath/TEXTGROUP-1-8_RESOURCE/U02_L2_T2_text_final.html
- ↑https://www.mathsisfun.com/numbers/fractions-division-whole-numbers.html
- ↑https://www.mathsisfun.com/least-common-denominator.html
Об этой статье
Соавтор(ы): David Jia. Дэвид Джиа — репетитор и основатель частной репетиторской компании LA Math Tutoring в Лос-Анджелесе, Калифорния. Имеет более 10 лет преподавательского опыта, работает с учащимися всех возрастов и классов над разными предметами, а также занимается конультированием по поступлению в колледж и подготовкой к SAT, ACT, ISEE и другим тестам. Набрав максимальные 800 баллов за SAT по математике и 690 — по английскому языку, получил стипендию Дикинсона в Университете Майами, который окончил со степенью бакалавра делового администрирования. Кроме того, был инструктором в обучающих онлайн-видео компаний, выпускающих учебники, таких как Larson Texts, Big Ideas Learning и Big Ideas Math. Количество просмотров этой статьи: 220 690.