Pull to refresh

Comments 29

10 ньютонов * 1 час (если помните физику, то тут результат должен быть в Джоулях).

Джоуль — это вообще-то ньютон-метр, а не ньютон-секунда...

Хехе, значит это я уже физику не помню ))) Исправил :)
Интересно, как обучить калькулятор понимать следующее:

1. радианы в секунду (рад/с) после умножения на метры (м) дают метры в секунду (м/с);
2. ватты, вары и вольт-амперы нельзя складывать друг с другом, но все три можно складывать с вольтами умноженными на амперы…
Ну я уже с треском провалил экзамен по физике судя по вашему предыдущему комментарию, но попробую объяснить свою точку зрения по этим 2 вопросам.

Прежде всего о радианах — цитата из Википедии:
Радиа́н — угол, соответствующий дуге, длина которой равна её радиусу.… Так как величина угла, выраженная в радианах, равна отношению длины дуги окружности (м) к длине её радиуса (м), угол в радианном измерении — величина безразмерная.


Получается, что размерность «рад/с» — это просто 1/с (секунды в минус первой степени). Домножаем на метры и получаем м/с. Получается, что калькулятор это понимает и справится.

По второму пункту. Давайте посчитаем вектор размерности для каждого из 3:
Вт = кг * м2/с3
Вары = Вольт-Ампер (см. ниже) * синус угла (константа) = м2 * кг / с3
Вольт-Ампер = м2 * кг / с3 / A (Вольт) * А = м2 * кг / с3

Размерность у Ватта и Вольт-Ампера одинаковая (и у вара). А почему их нельзя складывать? Если я правильно понимаю суть вопроса, то это как складывать метры и дециметры. Тупо прямой математикой нельзя, т.к. шкалы отличаются, но если их привести к одной шкале, то их можно сложить ведь обе вещи по сути — это дистанция. Калькулятор из этой статьи как раз это и делает — сначала он удостоверится, что размерности не противоречат, а потом посчитает абсолютное кол-во обоих операндов (за счет декомпозиции в базовые измерения) и сложит их. И в этом был смысл создания калькулятора, чтобы он абстрагировал все эти вопросы от человека. В ответе у вас будет 100500 условных мощностей. И потом вы эти 100500 условных мощностей можете сконвертировать обратно либо в Вары либо в Вт либо еще во что-нибудь из разряда мощности.

Таким образом в случае с этим калькулятром вам только нужно объяснить ему как декомпозируются Ватты, Вары и Вольт-Амперы в базовые единицы (кг, м, с). И он уже будет готов для вас посчитать 50 Вт + 10 Вар = ?? Вольт-Ампер
Их нельзя складывать потому что это единицы измерения для разных видов мощности. Сумма активной мощности с реактивной физического смысла не имеет…

Что же до радиан — тут фокус в том, что при сложении радиан друг с другом это самое обозначение «рад» нужно оставить, а вот при умножении рад/с на м радианы должны пропасть.
Я к сожалению действительно не разбираюсь в этом предмете. Я впервые слышу о варе. Моя логика заключается в том, что если 2 величины имеют одинаковый физический смысл, то они должны иметь одинаковую размерность. И противоположное — если 2 величины имеют разный физический смысл, то их размерности должны отличаться. Иначе в чем смысл размерности? По крайней мере я это так усвоил на уроках школы. И именно на этом строил анализ предметной области.

Про радианы, кажется, это больше похоже на косметический вопрос. Я бы его тогда решал какой-нибудь дополнительной оберткой, которая реализует эту логику «показывать / не показывать» рад.
Сумма активной мощности с реактивной физического смысла не имеет…

Это более высокий уровень анализа. Для калькулятора: и то, и другое — единицы мощности. А то, что юзер невалидную формулу вбил — это не калькуляторова зона ответственности.

Что же до радиан

То это безразмерная единица, которую вообще можно не указывать.
Поуглил электротехнику. Всё оказалось проще.
Реактивная мощность это про переменный ток, а переменный ток — это комплексные вычисления.
вар = В*А*i
где i — мнимая единица.
имеешьЛиТыБезразмерныйЧлен()
Это юмор? Кэп?

Как можно случайно вместо содержитБезразмерныйЧлен написать имеешьЛиТыБезразмерныйЧлен ?

C vs F “Попытайтесь проанализировать что же можно сделать с этой проблемой”
Да нет ни какой проблемы!
Есть системы измерения для примера СИ и СГС. И в общем виде нельзя даже складывать метр из СИ и метр из СГС.
Да и вы пытаетесь изобрести велосипед. В «ALU с размерностями» все делается очень просто:
Value = record{
Num: float;
Units: listOfUnits; };

listOfUnits = list{
unit: UnitType; };

UnitType = record{
UnitsName: string; // правильней через справочник
Power: integer;}

И все перед операцией проверяем совместимость размерностей. Если размерности не совпадают ошибка.
Если же вам необходимо преобразовывать размерности то это чуть искусство, т.к. в общем виде нельзя сказать в какие величины для удобства надо преобразовать значения для примера:
Вт = кг*м*м/(с*с*с).
Вт = Дж / с
Вт = H•м/с
Вт = В•А.
В вашем случаи про фаренгейты вообще все просто. Елси ввели фаренгейты сразу преобразуйте в вашу систему измерения. Если же вам ценны «оригинальные названия» и величины введи два дополнительных поля.
Я понимаю, что метры из SI и из других стандартов могут отличаться. Но в рамках этого калькулятора я обусловился, что метр он один… будь он из SI или из СГС. А если хочется иметь и тот и другой метр под рукой, то можно ввести дополнительную единицу измерений для этих целей: метр — пускай будет из SI. А метр_СГС — пускай будет «другой метр». Тогда в таблицу декомпозиций добавим информацию о том, как метр_СГС декомпозируется в обыкновенный метр, и дело в шляпе.

А как вы на этих 3х структурах данных посчитаете 10 метров + 3 фута? Ведь вам помимо размерности еще нужно отслежитвать и численно, как метры соотносятся к футам.

Я оставил часть про «искусство» наружу при конвертации результата к какой-то единице измерений. В моей логике существует количество и размерность этого количества. Тогда тот, кто пользуется моим калькулятором сам может сказать к какому виду привести это количество (к В*А или кДж/с, к примеру… или даже кДж/час). Калькулятор в этом плане не накладывает никаких ограничений, а скорее наоборот, оставляет полную свободу тому, кто будет им пользоваться.

Про фаренгейты я вас понял. Но т.к. у нас не просто конвертатор величин, а калькулятор, как тогда быть в следующей ситуации: человек пишет в калькулятор: 10 F * 10 = ?? F. Логично предположить, что он ожидает в ответ 100 F. Но т.к. внутренне калькулятор автоматически приведет температуру к Цельсию, умножит на 10, приведет обратно к Фаренгейтам, то ответ будет другим. И тогда пользователь подумает, что наш калькулятор не работает =) Я не говорю, что такое решение проблемы неправильное. Я пытаюсь показать, какие проблемы оно может повлечь за собой. Хотя решение действительно покрывает большинство сценариев и довольно просто в своей реализации.
Не к цельсиям, а к кельвинам. А вообще, ну нельзя же умножать температуру на число!
Ваша правда. В Кельвинах будет еще правильнее.

А почему нельзя? Если мы можем сказать, что объект А теплее чем объект Б. И мы можем сказать, что объект А теплее чем объект Б на 10 градусов Кельвина. То вроде бы у нас есть измеряемая и соотносимая шкала и на такой шкале можно проводить операции умножения.
Как раз только температура в кельвинах даёт соотносимую шкалу с «естественным» нулём.
Нет такого понятия как градус Кельвина. градусы у Цельсия и Фарингейта. А Кельвина так и есть Кельвина.
Ну, если нельзя, но очень хочется, то можно (с), если уж так хочется ответственность за физический смысл формулы переложить на спрашивающего. Тогда 10°F*10 = Fahrenheit(10*Kelvin(10°F)) = Fahrenheit(10*260.9 K) = 4237 °F. Представляю глаза пользователя, решившего умножить десять фаренгейтов на 10 и получившего 4 тысячи градусов :D
нельзя же умножать температуру на число
Если температура в кельвинах, то можно.
А если у нас градусы Цельсия или Фаренгейта, то умножение имеет смысл, когда это разность температур (задачи про теплоёмкость и т.д.): «полпинты воды нагрели на 10 градусов Фаренгейта — сколько энергии потрачено при КПД 25%?» — и тогда прибавлять/отнимать 32 не нужно.
Классическая
цитата ещё была:
In metric, one milliliter of water occupies one cubic centimeter, weighs one gram, and requires one calorie of energy to heat up by one degree centigrade—which is 1 percent of the difference between its freezing point and its boiling point. An amount of hydrogen weighing the same amount has exactly one mole of atoms in it. Whereas in the American system, the answer to ‘How much energy does it take to boil a room-temperature gallon of water?’ is ‘Go fuck yourself,’ because you can’t directly relate any of those quantities.

Перевод (не мой)
В метрической системе мер один миллилитр воды занимает один кубический сантиметр, весит один грамм, и потребуется одна калория энергии, чтобы нагреть его на один градус Цельсия, что составляет один процент разницы между точками ее замерзания и кипения. Водород той же массы содержит один моль атомов.
В американской же системе мер ответом на вопрос «Сколько энергии потребуется, чтобы довести до кипения галлон воды комнатной температуры?» будет «Пошел нахер», потому что не получится напрямую сопоставить ни одну из используемых величин.

В американской же системе мер ответом на вопрос «Сколько энергии потребуется, чтобы довести до кипения галлон воды комнатной температуры?»


BTU определяется как количество тепла, необходимое для того, чтобы поднять температуру 1 фунта воды на 1 градус Фаренгейта

Попытайтесь проанализировать что же можно сделать с этой проблемой.

Всё просто: температура по Цельсию и температура по Фаренгейту — это разные физические величины. Да, связанные друг с другом через линейную функцию, но разные.
Температура по Цельсию и абсолютная температура — то же разные, но измеряемые в единицах одного масштаба — как высота над уровнем моря и расстояние от центра Земли.
Т.е. с точки зрения реализации, нужно вводить единиц единицы измерения температуры, которые конвертируются друг в друга умножением на коэффициент, и нули температурных шкал, заданные в абсолютной шкале.

С мат. операциями — сложнее.
Невозможно вычислить 10°С + 15°F, не зная, что имел в виду автор. Зато 10°C — 15°F — можно, т.к. что имел в виду автор — очевидно.
Дальше, температуру по Цельсию или Фаренгейту нельзя ни на что умножить без потери смысла, а вот разность температур (не зависимо от единиц измерения) — можно.
Нужно как-то различать температуру — как точку на оси, и разность температур.

Хотя, возможно, как и в случае с Вольт-Амперами-реактивными, это не калькуляторова зона ответственности. Аргумент функции — ещё можно сконвертировать из произвольной допустимой шкалы в ожидаемую, но значение в выражении — неясно к чему конвертировать, не хватает метаданных.
Зато 10°C — 15°F — можно, т.к. что имел в виду автор — очевидно.

Тоже нельзя. Потому что 10 и 15 могут быть как значениями температуры, так и значениями разности температур, и ответ от этого изменится.

Придумал, как бы я решил эту проблему (не вполне корректно с точки зрения формы записи): знак градуса у меня был бы признаком температуры, а его отсутствия обозначало бы разность температур в указанных единицах.
Читая начало статьи (там где про физику и т.п.), думал предложить в комментариях сравнение с этим www.boost.org/doc/libs/1_67_0/doc/html/boost_units.html. Но увидев далее в статье PHP код, понял, что это будет слишком жестоко. )))
Cпасибо за ссылку! Было очень интересно почитать, как оно реализовано в той библиотеке.

У них введено еще понятие системы исчислений, и каждая единица измерений «живет» в своей системе. У меня в калькуляторе этого уровня абстракции нет и получается, что есть лишь 1 одна единственная система. Я еще подсмотрел, как у них реализована конвертация между фаренгейтом-цельсием-кельвином (https://github.com/boostorg/units/blob/develop/include/boost/units/base_units/temperature/conversions.hpp). Тут в другой ветке обсуждают проблему с этой конвертацией, и в Boost библиотеке она тоже не решена и остается на совести того, кто использует код.

Еще одно отличие (и для моей конкретной задачи это было важно) — в той библиотеке нет функционала «сконвертируй 180 см в ___ футов + ___ дюймов». Там это нужно реализовывать в коде собственного приложения.
Нет, наличие отдельной абстракции «система исчисления» — это совсем не принципиальный нюанс. Т.е. это не базис библиотеки, а скорее надстройка над базисом (в принципе очень похожим на то, что в статье, разве что набор базовых единиц тут произвольный — вот это действительно чуть более абстрактный подход), представляющая собой просто наборы популярных предопределённых единиц.

А вот действительно принципиальным отличием является тот факт, что данная библиотека отрабатывает на этапе компиляции (она построена с помощью метапрограммирования), а не исполнения. Т.е. если записывать какие-то формулы физических расчётов в C++ коде, то компилятор просто не даст собраться программе с неверное (с точки зрения единиц измерения) формулой.

Еще одно отличие (и для моей конкретной задачи это было важно) — в той библиотеке нет функционала «сконвертируй 180 см в ___ футов + ___ дюймов». Там это нужно реализовывать в коде собственного приложения.

Это да. Но это потому что собственно в технической (научной, инженерной и т.п.) практике такое обычно не используют, вне зависимости от системы единиц. Т.е. если у нас есть допустим 1,5*10^3 м, то мы можем это красиво записать как «1500 метров» или «1,5 километра», но не как «1 километр 500 метров».
На ПХП было бы трудно реализовать валидацию физического смысла на этапе компиляции :) В моей задаче не программисты кодировали вычисления, а юзер вводил выражения. У меня это действительно как калькулятор использовалось. Оттуда же и была необходимость в возможности привести величину к определенному виду (это о футах + дюймах).
Sign up to leave a comment.

Articles

Change theme settings