Доброго дня. Простите за ламерский вопрос, но все же
Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия:
1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4"
2. Точность не больше двух знаков после запятой. 1.234 -> "1.23".
Все!
В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю.
С++-ные варианты выдают подмножество С-шных, которые не устраивают.
Наверное, сейчас в меня полетят помидоры
Здравствуйте, Went, Вы писали:
W>Доброго дня. Простите за ламерский вопрос, но все же W>Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия: W>1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4" W>2. Точность не больше двух знаков после запятой. 1.234 -> "1.23".
W>В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю.
%.2f / %.2g?
Есть ещё набор функций gcvt/ecvt/fcvt, там нельзя указать сколько знаков после запятой должно быть, но функции gcvt и ecvt возвращают положение десятичной точки (указатель char*), отступив пару цифр и влепив туда '\0' можно обрезать до двух знаков.
Здравствуйте, Maniacal, Вы писали: M>%.2f / %.2g? W>>В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю.
Я что-то неправильно пишу в строке форматирования?
Вариант %.2f всегда будет добавлять нули: 1.0f -> "1.00"
Вариант %.2g грешит экспонентами: 0.0000001f -> "1e-007p"
Здравствуйте, Went, Вы писали:
W>В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю.
а если близкое к нулю вручную округлить?
Re[2]: Простейшее форматирование плавающего в строку
Здравствуйте, night beast, Вы писали: NB>а если близкое к нулю вручную округлить?
Да, думаю, это будет работать. Просто, думал, есть стандартное решение.
Re[3]: Простейшее форматирование плавающего в строку
Здравствуйте, Went, Вы писали:
W>Вариант %.2f всегда будет добавлять нули: 1.0f -> "1.00"
Делаешь так, потом удаляешь из получившейся строки завершающие нули.
Под твои требования у printf-like функций или у iostream, действительно, нет нужной комбинации флагов форматирования.
Re[3]: Простейшее форматирование плавающего в строку
Здравствуйте, Went, Вы писали:
W>Здравствуйте, night beast, Вы писали: NB>>а если близкое к нулю вручную округлить? W>Да, думаю, это будет работать. Просто, думал, есть стандартное решение.
Почти стандартное, с округлением, как предложили выше.
Здравствуйте, Went, Вы писали:
W>Да, я так сначала и сделал, но оно стало превращать числа больше ста в экспоненту. Поэтому ".2" там не нужно, по-моему, просто "%g" достаточно.
а тебе для чего? если для рублей, то лучше в целыми работать..
Здравствуйте, Went, Вы писали:
W>Доброго дня. Простите за ламерский вопрос, но все же W>Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия: W>1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4" W>2. Точность не больше двух знаков после запятой. 1.234 -> "1.23". W>Все! W>В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю. W>С++-ные варианты выдают подмножество С-шных, которые не устраивают.
Может, стоит таки смириться с лишними нулями? Это действительно принципиально, или у тебя чисто спортивный интерес?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Went, Вы писали:
W>Доброго дня. Простите за ламерский вопрос, но все же W>Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия: W>1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4" W>2. Точность не больше двух знаков после запятой. 1.234 -> "1.23". W>Все! W>В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю. W>С++-ные варианты выдают подмножество С-шных, которые не устраивают.
Коду нужно больше юниттестов :)
Например, format(0.0625) выведет три символа после точки: 0.062. А format(1e-20) выведет в экспоненциальной форме 1e-20.
Здравствуйте, watchmaker, Вы писали:
R>>https://ideone.com/uxF948
W>Коду нужно больше юниттестов W>Например, format(0.0625) выведет три символа после точки: 0.062. А format(1e-20) выведет в экспоненциальной форме 1e-20.
Ну а если серьезно, то понятно, что происходит. Фактический параметр: 99999999999999.90625 — мантисса слишком велика, что вызывает ожидаемую погрешность в математических выражениях. А так как число близко к целой степени десятки, функция digits_before_point выдает 15 вместо ожидаемых 14. Что поделаешь, все имеет свою погрешность и свою область применимости. Наверное, и это можно исправить, путем усложнения функции digits_before_point. Стоит ли игра свеч, зависит от строгости требований.
В то же время, судя потому, как тебе пришлось извратиться для получения нужного литерала, попасть в такую ситуацию не так-то просто
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Went, Вы писали:
W>Доброго дня. Простите за ламерский вопрос, но все же W>Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия: W>1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4" W>2. Точность не больше двух знаков после запятой. 1.234 -> "1.23". W>Все! W>В С-шном формате есть %f и %g, но я нашел комбинации флагов, дающей нужного результата. Первый постоянно дописывает ненужные нули, даже если они не нужны, второе переводит в экспоненциальный формат, если число очень близко к нулю. W>С++-ные варианты выдают подмножество С-шных, которые не устраивают.
Вот другой подход к решению задачи: сформировать строку страндартными средствами, затем отбросить лишние нули. Косяки с потерей точности тоже можно поймать, но это косяки уже не мои
Здравствуйте, Went, Вы писали:
W>Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия: W>1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4" W>2. Точность не больше двух знаков после запятой. 1.234 -> "1.23". W>Все!
std::to_chars() c флагом std::chars_format::fixed делает то, что тебе нужно.
Кстати делает это исключительно быстро, т.к. ей плевать на локаль и подобную ересь
Здравствуйте, Videoman, Вы писали:
W>>Мне нужно превратить стандартными средствами float в строку, чтобы соблюдались следующие условия: W>>1. Лишние нули не пишутся, лишняя точка тоже. 1.1000f -> "1.1", 4f -> "4" W>>2. Точность не больше двух знаков после запятой. 1.234 -> "1.23". W>>Все!
V>std::to_chars() c флагом std::chars_format::fixed делает то, что тебе нужно.
Я попытался адаптировать пример здесь под требования задачи, но компилер ругается на std::chars_format почему-то
Я усомнился, а действительно ли он отбрасывает лишние нули. Ну, допустим, отбрасывает, тогда вопрос, как добиться такого же результата, как при работе с потоками и манипулятором std::fixed — то есть, чтоб нули НЕ отбрасывались?
--
Не можешь достичь желаемого — пожелай достигнутого.