Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
82dbc2ea
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
82dbc2ea
编写于
7月 26, 2015
作者:
R
Robin Kruppe
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add optional, external tests for floating point parsing.
Running these tests takes hours, so they are not run by @bors.
上级
ba792a4b
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
664 addition
and
0 deletion
+664
-0
src/etc/test-float-parse/_common.rs
src/etc/test-float-parse/_common.rs
+26
-0
src/etc/test-float-parse/few-ones.rs
src/etc/test-float-parse/few-ones.rs
+27
-0
src/etc/test-float-parse/huge-pow10.rs
src/etc/test-float-parse/huge-pow10.rs
+21
-0
src/etc/test-float-parse/many-digits.rs
src/etc/test-float-parse/many-digits.rs
+39
-0
src/etc/test-float-parse/rand-f64.rs
src/etc/test-float-parse/rand-f64.rs
+32
-0
src/etc/test-float-parse/runtests.py
src/etc/test-float-parse/runtests.py
+399
-0
src/etc/test-float-parse/short-decimals.rs
src/etc/test-float-parse/short-decimals.rs
+29
-0
src/etc/test-float-parse/subnorm.rs
src/etc/test-float-parse/subnorm.rs
+23
-0
src/etc/test-float-parse/tiny-pow10.rs
src/etc/test-float-parse/tiny-pow10.rs
+21
-0
src/etc/test-float-parse/u32-small.rs
src/etc/test-float-parse/u32-small.rs
+19
-0
src/etc/test-float-parse/u64-pow2.rs
src/etc/test-float-parse/u64-pow2.rs
+28
-0
未找到文件。
src/etc/test-float-parse/_common.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
std
::
io
;
use
std
::
io
::
prelude
::
*
;
use
std
::
mem
::
transmute
;
// Nothing up my sleeve: Just (PI - 3) in base 16.
#[allow(dead_code)]
pub
const
SEED
:
[
u32
;
3
]
=
[
0x243f_6a88
,
0x85a3_08d3
,
0x1319_8a2e
];
pub
fn
validate
(
text
:
String
)
{
let
mut
out
=
io
::
stdout
();
let
x
:
f64
=
text
.parse
()
.unwrap
();
let
f64_bytes
:
u64
=
unsafe
{
transmute
(
x
)
};
let
x
:
f32
=
text
.parse
()
.unwrap
();
let
f32_bytes
:
u32
=
unsafe
{
transmute
(
x
)
};
writeln!
(
&
mut
out
,
"{:016x} {:08x} {}"
,
f64_bytes
,
f32_bytes
,
text
)
.unwrap
();
}
src/etc/test-float-parse/few-ones.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
_
common
::
validate
;
fn
main
()
{
let
mut
pow
=
vec!
[];
for
i
in
0
..
63
{
pow
.push
(
1u64
<<
i
);
}
for
a
in
&
pow
{
for
b
in
&
pow
{
for
c
in
&
pow
{
validate
((
a
|
b
|
c
)
.to_string
());
}
}
}
}
src/etc/test-float-parse/huge-pow10.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
_
common
::
validate
;
fn
main
()
{
for
e
in
300
..
310
{
for
i
in
0
..
100000
{
validate
(
format!
(
"{}e{}"
,
i
,
e
));
}
}
}
src/etc/test-float-parse/many-digits.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rand)]
extern
crate
rand
;
mod
_
common
;
use
std
::
char
;
use
rand
::{
IsaacRng
,
Rng
,
SeedableRng
};
use
rand
::
distributions
::{
Range
,
Sample
};
use
_
common
::{
validate
,
SEED
};
fn
main
()
{
let
mut
rnd
=
IsaacRng
::
from_seed
(
&
SEED
);
let
mut
range
=
Range
::
new
(
0
,
10
);
for
_
in
0
..
5_000_000u64
{
let
num_digits
=
rnd
.gen_range
(
100
,
300
);
let
digits
=
gen_digits
(
num_digits
,
&
mut
range
,
&
mut
rnd
);
validate
(
digits
);
}
}
fn
gen_digits
<
R
:
Rng
>
(
n
:
u32
,
range
:
&
mut
Range
<
u32
>
,
rnd
:
&
mut
R
)
->
String
{
let
mut
s
=
String
::
new
();
for
_
in
0
..
n
{
let
digit
=
char
::
from_digit
(
range
.sample
(
rnd
),
10
)
.unwrap
();
s
.push
(
digit
);
}
s
}
src/etc/test-float-parse/rand-f64.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rand)]
extern
crate
rand
;
mod
_
common
;
use
_
common
::{
validate
,
SEED
};
use
rand
::{
IsaacRng
,
Rng
,
SeedableRng
};
use
std
::
mem
::
transmute
;
fn
main
()
{
let
mut
rnd
=
IsaacRng
::
from_seed
(
&
SEED
);
let
mut
i
=
0
;
while
i
<
10_000_000
{
let
bits
=
rnd
.next_u64
();
let
x
:
f64
=
unsafe
{
transmute
(
bits
)
};
if
x
.is_finite
()
{
validate
(
format!
(
"{:e}"
,
x
));
i
+=
1
;
}
}
}
src/etc/test-float-parse/runtests.py
0 → 100644
浏览文件 @
82dbc2ea
#!/usr/bin/python2.7
#
# Copyright 2015 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
"""
Testing dec2flt
===============
These are *really* extensive tests. Expect them to run for hours. Due to the
nature of the problem (the input is a string of arbitrary length), exhaustive
testing is not really possible. Instead, there are exhaustive tests for some
classes of inputs for which that is feasible and a bunch of deterministic and
random non-exhaustive tests for covering everything else.
The actual tests (generating decimal strings and feeding them to dec2flt) is
performed by a set of stand-along rust programs. This script compiles, runs,
and supervises them. In particular, the programs report the strings they
generate and the floating point numbers they converted those strings to.
You can run specific tests rather than all of them by giving their names
(without .rs extension) as command line parameters.
Verification
------------
The tricky part is not generating those inputs but verifying the outputs.
Comparing with the result of Python's float() does not cut it because
(and this is apparently undocumented) although Python includes a version of
Martin Gay's code including the decimal-to-float part, it doesn't actually use
it for float() (only for round()) instead relying on the system scanf() which
is not necessarily completely accurate.
Instead, we take the input and compute the true value with bignum arithmetic
(as a fraction, using the ``fractions`` module).
Given an input string and the corresponding float computed via Rust, simply
decode the float into f * 2^k (for intergers f, k) and the ULP.
We can now easily compute the error and check if it is within 0.5 ULP as it
should be. Zero and infinites are handled similarly:
- If the approximation is 0.0, the exact value should be *less or equal*
half the smallest denormal float: the smallest denormal floating point
number has an odd mantissa (00...001) and thus half of that is rounded
to 00...00, i.e., zero.
- If the approximation is Inf, the exact value should be *greater or equal*
to the largest finite float + 0.5 ULP: the largest finite float has an odd
mantissa (11...11), so that plus half an ULP is rounded up to the nearest
even number, which overflows.
Implementation details
----------------------
This directory contains a set of single-file Rust programs that perform
tests with a particular class of inputs. Each is compiled and run without
parameters, outputs (f64, f32, decimal) pairs to verify externally, and
in any case either exits gracefully or with a panic.
If a test binary writes *anything at all* to stderr or exits with an
exit code that's not 0, the test fails.
The output on stdout is treated as (f64, f32, decimal) record, encoded thusly:
- The first eight bytes are a binary64 (native endianness).
- The following four bytes are a binary32 (native endianness).
- Then the corresponding string input follows, in ASCII (no newline).
- The record is terminated with a newline.
Incomplete records are an error. Not-a-Number bit patterns are invalid too.
The tests run serially but the validaition for a a single test is parallelized
with ``multiprocessing``. Each test is launched as a subprocess.
One thread supervises it: Accepts and enqueues records to validate, observe
stderr, and waits for the process to exit. A set of worker processes perform
the validation work for the outputs enqueued there. Another thread listens
for progress updates from the workers.
Known issues
------------
Some errors (e.g., NaN outputs) aren't handled very gracefully.
Also, if there is an exception or the process is interrupted (at least on
Windows) the worker processes are leaked and stick around forever.
They're only a few megabytes each, but still, this script should not be run
if you aren't prepared to manually kill a lot of orphaned processes.
"""
from
__future__
import
print_function
import
sys
import
os.path
import
time
import
struct
from
fractions
import
Fraction
from
collections
import
namedtuple
from
subprocess
import
Popen
,
check_call
,
PIPE
from
glob
import
glob
import
multiprocessing
import
Queue
import
threading
import
ctypes
import
binascii
NUM_WORKERS
=
2
UPDATE_EVERY_N
=
50000
INF
=
namedtuple
(
'INF'
,
''
)()
NEG_INF
=
namedtuple
(
'NEG_INF'
,
''
)()
ZERO
=
namedtuple
(
'ZERO'
,
''
)()
MAILBOX
=
None
# The queue for reporting errors to the main process.
STDOUT_LOCK
=
threading
.
Lock
()
test_name
=
None
child_processes
=
[]
exit_status
=
0
def
msg
(
*
args
):
with
STDOUT_LOCK
:
print
(
"["
+
test_name
+
"]"
,
*
args
)
sys
.
stdout
.
flush
()
def
write_errors
():
global
exit_status
f
=
open
(
"errors.txt"
,
'w'
)
have_seen_error
=
False
while
True
:
args
=
MAILBOX
.
get
()
if
args
is
None
:
f
.
close
()
break
print
(
*
args
,
file
=
f
)
f
.
flush
()
if
not
have_seen_error
:
have_seen_error
=
True
msg
(
"Something is broken:"
,
*
args
)
msg
(
"Future errors logged to errors.txt"
)
exit_status
=
101
def
rustc
(
test
):
rs
=
test
+
'.rs'
exe
=
test
+
'.exe'
# hopefully this makes it work on *nix
print
(
"compiling"
,
test
)
sys
.
stdout
.
flush
()
check_call
([
'rustc'
,
rs
,
'-o'
,
exe
])
def
run
(
test
):
global
test_name
test_name
=
test
t0
=
time
.
clock
()
msg
(
"setting up supervisor"
)
exe
=
test
+
'.exe'
proc
=
Popen
(
exe
,
bufsize
=
1
<<
20
,
stdin
=
PIPE
,
stdout
=
PIPE
,
stderr
=
PIPE
)
done
=
multiprocessing
.
Value
(
ctypes
.
c_bool
)
queue
=
multiprocessing
.
Queue
(
maxsize
=
5
)
#(maxsize=1024)
workers
=
[]
for
n
in
range
(
NUM_WORKERS
):
worker
=
multiprocessing
.
Process
(
name
=
'Worker-'
+
str
(
n
+
1
),
target
=
init_worker
,
args
=
[
test
,
MAILBOX
,
queue
,
done
])
workers
.
append
(
worker
)
child_processes
.
append
(
worker
)
for
worker
in
workers
:
worker
.
start
()
msg
(
"running test"
)
interact
(
proc
,
queue
)
with
done
.
get_lock
():
done
.
value
=
True
for
worker
in
workers
:
worker
.
join
()
msg
(
"python is done"
)
assert
queue
.
empty
(),
"did not validate everything"
dt
=
time
.
clock
()
-
t0
msg
(
"took"
,
round
(
dt
,
3
),
"seconds"
)
def
interact
(
proc
,
queue
):
line
=
""
n
=
0
while
proc
.
poll
()
is
None
:
line
=
proc
.
stdout
.
readline
()
if
not
line
:
continue
assert
line
.
endswith
(
'
\n
'
),
"incomplete line: "
+
repr
(
line
)
queue
.
put
(
line
)
line
=
""
n
+=
1
if
n
%
UPDATE_EVERY_N
==
0
:
msg
(
"got"
,
str
(
n
//
1000
)
+
"k"
,
"records"
)
msg
(
"rust is done. exit code:"
,
proc
.
returncode
)
rest
,
stderr
=
proc
.
communicate
()
if
stderr
:
msg
(
"rust stderr output:"
,
stderr
)
for
line
in
rest
.
split
(
'
\n
'
):
if
not
line
:
continue
queue
.
put
(
line
)
def
main
():
global
MAILBOX
tests
=
[
os
.
path
.
splitext
(
f
)[
0
]
for
f
in
glob
(
'*.rs'
)
if
not
f
.
startswith
(
'_'
)]
whitelist
=
sys
.
argv
[
1
:]
if
whitelist
:
tests
=
[
test
for
test
in
tests
if
test
in
whitelist
]
if
not
tests
:
print
(
"Error: No tests to run"
)
sys
.
exit
(
1
)
# Compile first for quicker feedback
for
test
in
tests
:
rustc
(
test
)
# Set up mailbox once for all tests
MAILBOX
=
multiprocessing
.
Queue
()
mailman
=
threading
.
Thread
(
target
=
write_errors
)
mailman
.
daemon
=
True
mailman
.
start
()
for
test
in
tests
:
if
whitelist
and
test
not
in
whitelist
:
continue
run
(
test
)
MAILBOX
.
put
(
None
)
mailman
.
join
()
# ---- Worker thread code ----
POW2
=
{
e
:
Fraction
(
2
)
**
e
for
e
in
range
(
-
1100
,
1100
)
}
HALF_ULP
=
{
e
:
(
Fraction
(
2
)
**
e
)
/
2
for
e
in
range
(
-
1100
,
1100
)
}
DONE_FLAG
=
None
def
send_error_to_supervisor
(
*
args
):
MAILBOX
.
put
(
args
)
def
init_worker
(
test
,
mailbox
,
queue
,
done
):
global
test_name
,
MAILBOX
,
DONE_FLAG
test_name
=
test
MAILBOX
=
mailbox
DONE_FLAG
=
done
do_work
(
queue
)
def
is_done
():
with
DONE_FLAG
.
get_lock
():
return
DONE_FLAG
.
value
def
do_work
(
queue
):
while
True
:
try
:
line
=
queue
.
get
(
timeout
=
0.01
)
except
Queue
.
Empty
:
if
queue
.
empty
()
and
is_done
():
return
else
:
continue
bin64
,
bin32
,
text
=
line
.
rstrip
().
split
()
validate
(
bin64
,
bin32
,
text
)
def
decode_binary64
(
x
):
"""
Turn a IEEE 754 binary64 into (mantissa, exponent), except 0.0 and
infinity (positive and negative), which return ZERO, INF, and NEG_INF
respectively.
"""
x
=
binascii
.
unhexlify
(
x
)
assert
len
(
x
)
==
8
,
repr
(
x
)
[
bits
]
=
struct
.
unpack
(
b
'>Q'
,
x
)
if
bits
==
0
:
return
ZERO
exponent
=
(
bits
>>
52
)
&
0x7FF
negative
=
bits
>>
63
low_bits
=
bits
&
0xFFFFFFFFFFFFF
if
exponent
==
0
:
mantissa
=
low_bits
exponent
+=
1
if
mantissa
==
0
:
return
ZERO
elif
exponent
==
0x7FF
:
assert
low_bits
==
0
,
"NaN"
if
negative
:
return
NEG_INF
else
:
return
INF
else
:
mantissa
=
low_bits
|
(
1
<<
52
)
exponent
-=
1023
+
52
if
negative
:
mantissa
=
-
mantissa
return
(
mantissa
,
exponent
)
def
decode_binary32
(
x
):
"""
Turn a IEEE 754 binary32 into (mantissa, exponent), except 0.0 and
infinity (positive and negative), which return ZERO, INF, and NEG_INF
respectively.
"""
x
=
binascii
.
unhexlify
(
x
)
assert
len
(
x
)
==
4
,
repr
(
x
)
[
bits
]
=
struct
.
unpack
(
b
'>I'
,
x
)
if
bits
==
0
:
return
ZERO
exponent
=
(
bits
>>
23
)
&
0xFF
negative
=
bits
>>
31
low_bits
=
bits
&
0x7FFFFF
if
exponent
==
0
:
mantissa
=
low_bits
exponent
+=
1
if
mantissa
==
0
:
return
ZERO
elif
exponent
==
0xFF
:
if
negative
:
return
NEG_INF
else
:
return
INF
else
:
mantissa
=
low_bits
|
(
1
<<
23
)
exponent
-=
127
+
23
if
negative
:
mantissa
=
-
mantissa
return
(
mantissa
,
exponent
)
MIN_SUBNORMAL_DOUBLE
=
Fraction
(
2
)
**
-
1074
MIN_SUBNORMAL_SINGLE
=
Fraction
(
2
)
**
-
149
# XXX unsure
MAX_DOUBLE
=
(
2
-
Fraction
(
2
)
**
-
52
)
*
(
2
**
1023
)
MAX_SINGLE
=
(
2
-
Fraction
(
2
)
**
-
23
)
*
(
2
**
127
)
MAX_ULP_DOUBLE
=
1023
-
52
MAX_ULP_SINGLE
=
127
-
23
DOUBLE_ZERO_CUTOFF
=
MIN_SUBNORMAL_DOUBLE
/
2
DOUBLE_INF_CUTOFF
=
MAX_DOUBLE
+
2
**
(
MAX_ULP_DOUBLE
-
1
)
SINGLE_ZERO_CUTOFF
=
MIN_SUBNORMAL_SINGLE
/
2
SINGLE_INF_CUTOFF
=
MAX_SINGLE
+
2
**
(
MAX_ULP_SINGLE
-
1
)
def
validate
(
bin64
,
bin32
,
text
):
double
=
decode_binary64
(
bin64
)
single
=
decode_binary32
(
bin32
)
real
=
Fraction
(
text
)
if
double
is
ZERO
:
if
real
>
DOUBLE_ZERO_CUTOFF
:
record_special_error
(
text
,
"f64 zero"
)
elif
double
is
INF
:
if
real
<
DOUBLE_INF_CUTOFF
:
record_special_error
(
text
,
"f64 inf"
)
elif
double
is
NEG_INF
:
if
-
real
<
DOUBLE_INF_CUTOFF
:
record_special_error
(
text
,
"f64 -inf"
)
elif
len
(
double
)
==
2
:
sig
,
k
=
double
validate_normal
(
text
,
real
,
sig
,
k
,
"f64"
)
else
:
assert
0
,
"didn't handle binary64"
if
single
is
ZERO
:
if
real
>
SINGLE_ZERO_CUTOFF
:
record_special_error
(
text
,
"f32 zero"
)
elif
single
is
INF
:
if
real
<
SINGLE_INF_CUTOFF
:
record_special_error
(
text
,
"f32 inf"
)
elif
single
is
NEG_INF
:
if
-
real
<
SINGLE_INF_CUTOFF
:
record_special_error
(
text
,
"f32 -inf"
)
elif
len
(
single
)
==
2
:
sig
,
k
=
single
validate_normal
(
text
,
real
,
sig
,
k
,
"f32"
)
else
:
assert
0
,
"didn't handle binary32"
def
record_special_error
(
text
,
descr
):
send_error_to_supervisor
(
text
.
strip
(),
"wrongly rounded to"
,
descr
)
def
validate_normal
(
text
,
real
,
sig
,
k
,
kind
):
approx
=
sig
*
POW2
[
k
]
error
=
abs
(
approx
-
real
)
if
error
>
HALF_ULP
[
k
]:
record_normal_error
(
text
,
error
,
k
,
kind
)
def
record_normal_error
(
text
,
error
,
k
,
kind
):
one_ulp
=
HALF_ULP
[
k
+
1
]
assert
one_ulp
==
2
*
HALF_ULP
[
k
]
relative_error
=
error
/
one_ulp
text
=
text
.
strip
()
try
:
err_repr
=
float
(
relative_error
)
except
ValueError
:
err_repr
=
str
(
err_repr
).
replace
(
'/'
,
' / '
)
send_error_to_supervisor
(
err_repr
,
"ULP error on"
,
text
,
"("
+
kind
+
")"
)
if
__name__
==
'__main__'
:
main
()
src/etc/test-float-parse/short-decimals.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
_
common
::
validate
;
fn
main
()
{
// Skip e = 0 because small-u32 already does those.
for
e
in
1
..
301
{
for
i
in
0
..
10000
{
// If it ends in zeros, the parser will strip those (and adjust the exponent),
// which almost always (except for exponents near +/- 300) result in an input
// equivalent to something we already generate in a different way.
if
i
%
10
==
0
{
continue
;
}
validate
(
format!
(
"{}e{}"
,
i
,
e
));
validate
(
format!
(
"{}e-{}"
,
i
,
e
));
}
}
}
src/etc/test-float-parse/subnorm.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
std
::
mem
::
transmute
;
use
_
common
::
validate
;
fn
main
()
{
for
bits
in
0u32
..
(
1
<<
21
)
{
let
single
:
f32
=
unsafe
{
transmute
(
bits
)
};
validate
(
format!
(
"{:e}"
,
single
));
let
double
:
f64
=
unsafe
{
transmute
(
bits
as
u64
)
};
validate
(
format!
(
"{:e}"
,
double
));
}
}
src/etc/test-float-parse/tiny-pow10.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
_
common
::
validate
;
fn
main
()
{
for
e
in
301
..
327
{
for
i
in
0
..
100000
{
validate
(
format!
(
"{}e-{}"
,
i
,
e
));
}
}
}
src/etc/test-float-parse/u32-small.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
_
common
::
validate
;
fn
main
()
{
for
i
in
0
..
(
1
<<
19
)
{
validate
(
i
.to_string
());
}
}
src/etc/test-float-parse/u64-pow2.rs
0 → 100644
浏览文件 @
82dbc2ea
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
_
common
;
use
_
common
::
validate
;
use
std
::
u64
;
fn
main
()
{
for
exp
in
19
..
64
{
let
power
:
u64
=
1
<<
exp
;
validate
(
power
.to_string
());
for
offset
in
1
..
123
{
validate
((
power
+
offset
)
.to_string
());
validate
((
power
-
offset
)
.to_string
());
}
}
for
offset
in
0
..
123
{
validate
((
u64
::
MAX
-
offset
)
.to_string
());
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录