Skip to content

Commit 5d68e65

Browse files
committed
Incorporate FROGGS++'s changes.
1 parent 30a0f0f commit 5d68e65

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

src/HLL/sprintf.nqp

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -148,75 +148,79 @@ my module sprintf {
148148
make $int
149149
}
150150

151-
sub pad-with-sign($num, $size, $pad, $suffix) {
151+
sub pad-with-sign($sign, $num, $size, $pad) {
152152
if $pad ne ' ' && $size {
153-
my $sign := $num < 0 ?? '-' !! '';
154-
$num := nqp::abs_n($num);
155-
$num := $num ~ $suffix;
156-
$num := $sign ~ infix_x($pad, $size - nqp::chars($num) - 1) ~ $num;
153+
$sign ~ infix_x($pad, $size - nqp::chars($num) - 1) ~ $num;
157154
} else {
158-
$num := $num ~ $suffix;
155+
$sign ~ $num;
159156
}
160-
$num;
161157
}
162-
sub round-to-precision($float, $precision) {
163-
$float := $float * $precision;
164-
$float := $float - nqp::floor_n($float) >= 0.5 ?? nqp::ceil_n($float) !! nqp::floor_n($float);
165-
$float := $float / $precision;
158+
sub stringify-to-precision($float, $precision) {
159+
$float := nqp::abs_n($float);
160+
my $lhs := nqp::floor_n($float);
161+
my $rhs := $float - $lhs;
162+
163+
my $knowhow := nqp::knowhow().new_type(:repr("P6bigint"));
164+
my $int := nqp::box_i($lhs, $knowhow);
165+
$lhs := nqp::tostr_I($int);
166+
167+
$float := $rhs + 1;
168+
$float := $float * nqp::pow_n(10, $precision);
169+
$float := ~nqp::floor_n($float + 0.5);
170+
$float := $float - nqp::pow_n(10, $precision);
171+
$rhs := infix_x('0', $precision - nqp::chars($float)) ~ $float;
172+
$rhs := nqp::substr($rhs, nqp::chars($rhs) - $precision);
173+
174+
$float := $lhs ~ '.' ~ $rhs;
166175
}
167176
sub fixed-point($float, $precision, $size, $pad) {
168-
$float := round-to-precision($float, $precision);
169-
pad-with-sign($float, $size, $pad, '');
177+
my $sign := $float < 0 ?? '-' !! '';
178+
$float := stringify-to-precision(nqp::abs_n($float), $precision);
179+
pad-with-sign($sign, $float, $size, $pad);
170180
}
171181
sub scientific($float, $e, $precision, $size, $pad) {
172-
my $exp := nqp::floor_n(nqp::log_n(nqp::abs_n($float)) / nqp::log_n(10));
182+
my $sign := $float < 0 ?? '-' !! '';
183+
$float := nqp::abs_n($float);
184+
my $exp := nqp::floor_n(nqp::log_n($float) / nqp::log_n(10));
173185
$float := $float / nqp::pow_n(10, $exp);
174-
my $suffix := $e ~ '+' ~ $exp;
175-
$float := round-to-precision($float, $precision);
176-
pad-with-sign($float, $size, $pad, $suffix);
186+
$float := stringify-to-precision($float, $precision);
187+
$float := $float ~ $e ~ ($exp < 0 ?? '' !! '+') ~ $exp;
188+
pad-with-sign($sign, $float, $size, $pad);
177189
}
178190
sub shortest($float, $e, $precision, $size, $pad) {
179-
my $fixed := round-to-precision($float, $precision);
191+
my $sign := $float < 0 ?? '-' !! '';
192+
$float := nqp::abs_n($float);
193+
194+
my $fixed := stringify-to-precision($float, $precision);
180195

181196
my $exp := nqp::floor_n(nqp::log_n(nqp::abs_n($float)) / nqp::log_n(10));
182197
$float := $float / nqp::pow_n(10, $exp);
183-
my $suffix := $e ~ '+' ~ $exp;
184-
my $sci := round-to-precision($float, $precision);
198+
my $sci := stringify-to-precision($float, $precision) ~ $e ~ '+' ~ $exp;
185199

186200
if nqp::chars($sci) < nqp::chars($fixed) {
187-
pad-with-sign($sci, $size, $pad, $suffix);
201+
pad-with-sign($sign, $sci, $size, $pad);
188202
} else {
189-
pad-with-sign($fixed, $size, $pad, '');
203+
pad-with-sign($sign, $fixed, $size, $pad);
190204
}
191205
}
192206

193207
method directive:sym<e>($/) {
194208
my $float := next_argument();
195-
my $precision := nqp::pow_n(10, $<precision> ?? $<precision>.ast !! 6);
209+
my $precision := $<precision> ?? $<precision>.ast !! 6;
196210
my $pad := padding_char($/);
197211
my $size := $<size> ?? $<size>.ast !! 0;
198212
make scientific($float, $<sym>, $precision, $size, $pad);
199213
}
200214
method directive:sym<f>($/) {
201215
my $int := next_argument();
202-
my $sign := $int < 0 ?? '-' !! '';
203216
my $precision := $<precision> ?? $<precision>.ast !! 6;
204-
$int := nqp::abs_n($int) + 1;
205-
$int := $int * nqp::pow_n(10, $precision);
206-
$int := ~nqp::floor_n($int + 0.5);
207-
$int := $int - nqp::pow_n(10, $precision);
208-
my $lhs := nqp::chars($int) > $precision ?? nqp::substr($int, 0, nqp::chars($int) - $precision) !! '0';
209-
my $rhs := infix_x('0', $precision - nqp::chars($int)) ~ $int;
210-
$rhs := nqp::substr($rhs, nqp::chars($rhs) - $precision);
211-
$int := $lhs ~ '.' ~ $rhs;
212217
my $pad := padding_char($/);
213-
make $pad ne ' ' && $<size>
214-
?? $sign ~ infix_x($pad, $<size>.ast - nqp::chars($int) - 1) ~ $int
215-
!! $sign ~ $int
218+
my $size := $<size> ?? $<size>.ast !! 0;
219+
make fixed-point($int, $precision, $size, $pad);
216220
}
217221
method directive:sym<g>($/) {
218222
my $float := next_argument();
219-
my $precision := nqp::pow_n(10, $<precision> ?? $<precision>.ast !! 6);
223+
my $precision := $<precision> ?? $<precision>.ast !! 6;
220224
my $pad := padding_char($/);
221225
my $size := $<size> ?? $<size>.ast !! 0;
222226
make shortest($float, 'e', $precision, $size, $pad);

0 commit comments

Comments
 (0)