This documentation is automatically generated by online-judge-tools/verification-helper
#include "Src/Utility/FloatingMarkerShift.hpp"
文字列で受け取った小数を $10^t$ 倍して小数点を除去した整数にして返します。
引数は文字列 (std::string
)である必要があります。
i64 FloatingMarkerShift(const std::string& S, u32 shift)
const std::string& S
文字列として受け取った小数。
u32 shift
小数点を右に何回ずらすかを指定する。S
に対してshift
回右に小数点をずらしても小数点以下が $0$ で無い場合はassertにひっかかって死ぬ
計算結果。符号付き64
bit整数。
FloatingMarkerShift("1.23", 3) // 1230
FloatingMarkerShift("-0.01", 2) // -1
例えばこの問題 等で、浮動小数点型で入力を受け取ってそのまま $10$ 倍していって整数にした場合、誤差で死ぬ。
逆に、 $2$ 進数で値を保持しているということは $2$ 倍や $2$ で割るのにはかなり強(いらし)く、 例えばこの問題 では許容誤差が $10^{-9}$ とかなり厳しいが小数点以下が絡む割り算が $4$ しか無いので愚直にやっても普通にACが出た。
#pragma once
#include "../Template/TypeAlias.hpp"
#include <string>
#include <cassert>
#include <limits>
namespace zawa {
i64 FloatingMarkerShift(const std::string& S, u32 shift) {
static i64 lim10{std::numeric_limits<i64>::max() / 10};
assert(not S.empty());
i64 res{};
u32 moved{};
bool start{};
bool minus{S[0] == '-'};
for (u32 i{(u32)minus} ; i < S.size() ; i++) {
if (S[i] == '.') {
start = true;
}
else {
if (start) moved++;
assert(res < lim10);
res = res * 10;
assert(res < std::numeric_limits<i64>::max() - (S[i] - '0'));
res += S[i] - '0';
}
}
assert(moved <= shift);
while (moved < shift) {
moved++;
assert(res < lim10);
res = res * 10;
}
if (minus) res *= -1;
return res;
}
}// namespace zawa
#line 2 "Src/Utility/FloatingMarkerShift.hpp"
#line 2 "Src/Template/TypeAlias.hpp"
#include <cstdint>
#include <cstddef>
namespace zawa {
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using usize = std::size_t;
} // namespace zawa
#line 4 "Src/Utility/FloatingMarkerShift.hpp"
#include <string>
#include <cassert>
#include <limits>
namespace zawa {
i64 FloatingMarkerShift(const std::string& S, u32 shift) {
static i64 lim10{std::numeric_limits<i64>::max() / 10};
assert(not S.empty());
i64 res{};
u32 moved{};
bool start{};
bool minus{S[0] == '-'};
for (u32 i{(u32)minus} ; i < S.size() ; i++) {
if (S[i] == '.') {
start = true;
}
else {
if (start) moved++;
assert(res < lim10);
res = res * 10;
assert(res < std::numeric_limits<i64>::max() - (S[i] - '0'));
res += S[i] - '0';
}
}
assert(moved <= shift);
while (moved < shift) {
moved++;
assert(res < lim10);
res = res * 10;
}
if (minus) res *= -1;
return res;
}
}// namespace zawa