Line | Exclusive | Inclusive | Code |
---|---|---|---|
1 | # This file is a part of Julia. License is MIT: https://julialang.org/license | ||
2 | |||
3 | ## integer arithmetic ## | ||
4 | |||
5 | # The tuples and types that do not include 128 bit sizes are necessary to handle | ||
6 | # certain issues on 32-bit machines, and also to simplify promotion rules, as | ||
7 | # they are also used elsewhere where Int128/UInt128 support is separated out, | ||
8 | # such as in hashing2.jl | ||
9 | |||
10 | const BitSigned32_types = (Int8, Int16, Int32) | ||
11 | const BitUnsigned32_types = (UInt8, UInt16, UInt32) | ||
12 | const BitInteger32_types = (BitSigned32_types..., BitUnsigned32_types...) | ||
13 | |||
14 | const BitSigned64_types = (BitSigned32_types..., Int64) | ||
15 | const BitUnsigned64_types = (BitUnsigned32_types..., UInt64) | ||
16 | const BitInteger64_types = (BitSigned64_types..., BitUnsigned64_types...) | ||
17 | |||
18 | const BitSigned_types = (BitSigned64_types..., Int128) | ||
19 | const BitUnsigned_types = (BitUnsigned64_types..., UInt128) | ||
20 | const BitInteger_types = (BitSigned_types..., BitUnsigned_types...) | ||
21 | |||
22 | const BitSignedSmall_types = Int === Int64 ? ( Int8, Int16, Int32) : ( Int8, Int16) | ||
23 | const BitUnsignedSmall_types = Int === Int64 ? (UInt8, UInt16, UInt32) : (UInt8, UInt16) | ||
24 | const BitIntegerSmall_types = (BitSignedSmall_types..., BitUnsignedSmall_types...) | ||
25 | |||
26 | const BitSigned32 = Union{BitSigned32_types...} | ||
27 | const BitUnsigned32 = Union{BitUnsigned32_types...} | ||
28 | const BitInteger32 = Union{BitInteger32_types...} | ||
29 | |||
30 | const BitSigned64 = Union{BitSigned64_types...} | ||
31 | const BitUnsigned64 = Union{BitUnsigned64_types...} | ||
32 | const BitInteger64 = Union{BitInteger64_types...} | ||
33 | |||
34 | const BitSigned = Union{BitSigned_types...} | ||
35 | const BitUnsigned = Union{BitUnsigned_types...} | ||
36 | const BitInteger = Union{BitInteger_types...} | ||
37 | |||
38 | const BitSignedSmall = Union{BitSignedSmall_types...} | ||
39 | const BitUnsignedSmall = Union{BitUnsignedSmall_types...} | ||
40 | const BitIntegerSmall = Union{BitIntegerSmall_types...} | ||
41 | |||
42 | const BitSigned64T = Union{Type{Int8}, Type{Int16}, Type{Int32}, Type{Int64}} | ||
43 | const BitUnsigned64T = Union{Type{UInt8}, Type{UInt16}, Type{UInt32}, Type{UInt64}} | ||
44 | |||
45 | const BitIntegerType = Union{map(T->Type{T}, BitInteger_types)...} | ||
46 | |||
47 | ## integer comparisons ## | ||
48 | |||
49 | 1 (2.38%) | 1 (2.38%) | (<)(x::T, y::T) where {T<:BitSigned} = slt_int(x, y) |
50 | |||
51 | (-)(x::BitInteger) = neg_int(x) | ||
52 | (-)(x::T, y::T) where {T<:BitInteger} = sub_int(x, y) | ||
53 | 2 (4.76%) | 2 (4.76%) |
2 (4.76%) samples spent in +
(+)(x::T, y::T) where {T<:BitInteger} = add_int(x, y)
1 (50.00%) (ex.), 1 (50.00%) (incl.) when called from + line 803 1 (50.00%) (ex.), 1 (50.00%) (incl.) when called from binexp_cache line 254 |
54 | 1 (2.38%) | 1 (2.38%) |
1 (2.38%) samples spent in *
(*)(x::T, y::T) where {T<:BitInteger} = mul_int(x, y)
1 (100.00%) (ex.), 1 (100.00%) (incl.) when called from digitgen line 98 |
55 | |||
56 | inv(x::Integer) = float(one(x)) / float(x) | ||
57 | (/)(x::T, y::T) where {T<:Integer} = float(x) / float(y) | ||
58 | # skip promotion for system integer types | ||
59 | (/)(x::BitInteger, y::BitInteger) = float(x) / float(y) | ||
60 | |||
61 | """ | ||
62 | isodd(x::Integer) -> Bool | ||
63 | |||
64 | Return `true` if `x` is odd (that is, not divisible by 2), and `false` otherwise. | ||
65 | |||
66 | # Examples | ||
67 | ```jldoctest | ||
68 | julia> isodd(9) | ||
69 | true | ||
70 | |||
71 | julia> isodd(10) | ||
72 | false | ||
73 | ``` | ||
74 | """ | ||
75 | isodd(n::Integer) = rem(n, 2) != 0 | ||
76 | |||
77 | """ | ||
78 | iseven(x::Integer) -> Bool | ||
79 | |||
80 | Return `true` is `x` is even (that is, divisible by 2), and `false` otherwise. | ||
81 | |||
82 | # Examples | ||
83 | ```jldoctest | ||
84 | julia> iseven(9) | ||
85 | false | ||
86 | |||
87 | julia> iseven(10) | ||
88 | true | ||
89 | ``` | ||
90 | """ | ||
91 | iseven(n::Integer) = !isodd(n) | ||
92 | |||
93 | signbit(x::Integer) = x < 0 | ||
94 | signbit(x::Unsigned) = false | ||
95 | |||
96 | flipsign(x::T, y::T) where {T<:BitSigned} = flipsign_int(x, y) | ||
97 | flipsign(x::BitSigned, y::BitSigned) = flipsign_int(promote(x, y)...) % typeof(x) | ||
98 | |||
99 | flipsign(x::Signed, y::Float16) = flipsign(x, bitcast(Int16, y)) | ||
100 | flipsign(x::Signed, y::Float32) = flipsign(x, bitcast(Int32, y)) | ||
101 | flipsign(x::Signed, y::Float64) = flipsign(x, bitcast(Int64, y)) | ||
102 | flipsign(x::Signed, y::Real) = flipsign(x, -oftype(x, signbit(y))) | ||
103 | |||
104 | copysign(x::Signed, y::Signed) = flipsign(x, x ⊻ y) | ||
105 | copysign(x::Signed, y::Float16) = copysign(x, bitcast(Int16, y)) | ||
106 | copysign(x::Signed, y::Float32) = copysign(x, bitcast(Int32, y)) | ||
107 | copysign(x::Signed, y::Float64) = copysign(x, bitcast(Int64, y)) | ||
108 | copysign(x::Signed, y::Real) = copysign(x, -oftype(x, signbit(y))) | ||
109 | |||
110 | """ | ||
111 | abs(x) | ||
112 | |||
113 | The absolute value of `x`. | ||
114 | |||
115 | When `abs` is applied to signed integers, overflow may occur, | ||
116 | resulting in the return of a negative value. This overflow occurs only | ||
117 | when `abs` is applied to the minimum representable value of a signed | ||
118 | integer. That is, when `x == typemin(typeof(x))`, `abs(x) == x < 0`, | ||
119 | not `-x` as might be expected. | ||
120 | |||
121 | # Examples | ||
122 | ```jldoctest | ||
123 | julia> abs(-3) | ||
124 | 3 | ||
125 | |||
126 | julia> abs(1 + im) | ||
127 | 1.4142135623730951 | ||
128 | |||
129 | julia> abs(typemin(Int64)) | ||
130 | -9223372036854775808 | ||
131 | ``` | ||
132 | """ | ||
133 | function abs end | ||
134 | |||
135 | abs(x::Unsigned) = x | ||
136 | abs(x::Signed) = flipsign(x,x) | ||
137 | |||
138 | ~(n::Integer) = -n-1 | ||
139 | |||
140 | unsigned(x::BitSigned) = reinterpret(typeof(convert(Unsigned, zero(x))), x) | ||
141 | unsigned(x::Bool) = convert(Unsigned, x) | ||
142 | |||
143 | """ | ||
144 | unsigned(x) -> Unsigned | ||
145 | |||
146 | Convert a number to an unsigned integer. If the argument is signed, it is reinterpreted as | ||
147 | unsigned without checking for negative values. | ||
148 | |||
149 | # Examples | ||
150 | ```jldoctest | ||
151 | julia> unsigned(-2) | ||
152 | 0xfffffffffffffffe | ||
153 | |||
154 | julia> unsigned(2) | ||
155 | 0x0000000000000002 | ||
156 | |||
157 | julia> signed(unsigned(-2)) | ||
158 | -2 | ||
159 | ``` | ||
160 | """ | ||
161 | unsigned(x) = convert(Unsigned, x) | ||
162 | signed(x::Unsigned) = reinterpret(typeof(convert(Signed, zero(x))), x) | ||
163 | |||
164 | """ | ||
165 | signed(x) | ||
166 | |||
167 | Convert a number to a signed integer. If the argument is unsigned, it is reinterpreted as | ||
168 | signed without checking for overflow. | ||
169 | """ | ||
170 | signed(x) = convert(Signed, x) | ||
171 | |||
172 | div(x::BitSigned, y::Unsigned) = flipsign(signed(div(unsigned(abs(x)), y)), x) | ||
173 | div(x::Unsigned, y::BitSigned) = unsigned(flipsign(signed(div(x, unsigned(abs(y)))), y)) | ||
174 | |||
175 | rem(x::BitSigned, y::Unsigned) = flipsign(signed(rem(unsigned(abs(x)), y)), x) | ||
176 | rem(x::Unsigned, y::BitSigned) = rem(x, unsigned(abs(y))) | ||
177 | |||
178 | fld(x::Signed, y::Unsigned) = div(x, y) - (signbit(x) & (rem(x, y) != 0)) | ||
179 | fld(x::Unsigned, y::Signed) = div(x, y) - (signbit(y) & (rem(x, y) != 0)) | ||
180 | |||
181 | |||
182 | """ | ||
183 | mod(x, y) | ||
184 | rem(x, y, RoundDown) | ||
185 | |||
186 | The reduction of `x` modulo `y`, or equivalently, the remainder of `x` after floored | ||
187 | division by `y`, i.e. | ||
188 | ```julia | ||
189 | x - y*fld(x,y) | ||
190 | ``` | ||
191 | if computed without intermediate rounding. | ||
192 | |||
193 | The result will have the same sign as `y`, and magnitude less than `abs(y)` (with some | ||
194 | exceptions, see note below). | ||
195 | |||
196 | !!! note | ||
197 | |||
198 | When used with floating point values, the exact result may not be representable by the | ||
199 | type, and so rounding error may occur. In particular, if the exact result is very | ||
200 | close to `y`, then it may be rounded to `y`. | ||
201 | |||
202 | ```jldoctest | ||
203 | julia> mod(8, 3) | ||
204 | 2 | ||
205 | |||
206 | julia> mod(9, 3) | ||
207 | 0 | ||
208 | |||
209 | julia> mod(8.9, 3) | ||
210 | 2.9000000000000004 | ||
211 | |||
212 | julia> mod(eps(), 3) | ||
213 | 2.220446049250313e-16 | ||
214 | |||
215 | julia> mod(-eps(), 3) | ||
216 | 3.0 | ||
217 | ``` | ||
218 | """ | ||
219 | function mod(x::T, y::T) where T<:Integer | ||
220 | y == -1 && return T(0) # avoid potential overflow in fld | ||
221 | return x - fld(x, y) * y | ||
222 | end | ||
223 | mod(x::BitSigned, y::Unsigned) = rem(y + unsigned(rem(x, y)), y) | ||
224 | mod(x::Unsigned, y::Signed) = rem(y + signed(rem(x, y)), y) | ||
225 | mod(x::T, y::T) where {T<:Unsigned} = rem(x, y) | ||
226 | |||
227 | cld(x::Signed, y::Unsigned) = div(x, y) + (!signbit(x) & (rem(x, y) != 0)) | ||
228 | cld(x::Unsigned, y::Signed) = div(x, y) + (!signbit(y) & (rem(x, y) != 0)) | ||
229 | |||
230 | # Don't promote integers for div/rem/mod since there is no danger of overflow, | ||
231 | # while there is a substantial performance penalty to 64-bit promotion. | ||
232 | div(x::T, y::T) where {T<:BitSigned64} = checked_sdiv_int(x, y) | ||
233 | rem(x::T, y::T) where {T<:BitSigned64} = checked_srem_int(x, y) | ||
234 | div(x::T, y::T) where {T<:BitUnsigned64} = checked_udiv_int(x, y) | ||
235 | rem(x::T, y::T) where {T<:BitUnsigned64} = checked_urem_int(x, y) | ||
236 | |||
237 | |||
238 | # fld(x,y) == div(x,y) - ((x>=0) != (y>=0) && rem(x,y) != 0 ? 1 : 0) | ||
239 | fld(x::T, y::T) where {T<:Unsigned} = div(x,y) | ||
240 | function fld(x::T, y::T) where T<:Integer | ||
241 | d = div(x, y) | ||
242 | return d - (signbit(x ⊻ y) & (d * y != x)) | ||
243 | end | ||
244 | |||
245 | # cld(x,y) = div(x,y) + ((x>0) == (y>0) && rem(x,y) != 0 ? 1 : 0) | ||
246 | function cld(x::T, y::T) where T<:Unsigned | ||
247 | d = div(x, y) | ||
248 | return d + (d * y != x) | ||
249 | end | ||
250 | function cld(x::T, y::T) where T<:Integer | ||
251 | d = div(x, y) | ||
252 | return d + (((x > 0) == (y > 0)) & (d * y != x)) | ||
253 | end | ||
254 | |||
255 | ## integer bitwise operations ## | ||
256 | |||
257 | """ | ||
258 | ~(x) | ||
259 | |||
260 | Bitwise not. | ||
261 | |||
262 | # Examples | ||
263 | ```jldoctest | ||
264 | julia> ~4 | ||
265 | -5 | ||
266 | |||
267 | julia> ~10 | ||
268 | -11 | ||
269 | |||
270 | julia> ~true | ||
271 | false | ||
272 | ``` | ||
273 | """ | ||
274 | (~)(x::BitInteger) = not_int(x) | ||
275 | |||
276 | """ | ||
277 | &(x, y) | ||
278 | |||
279 | Bitwise and. Implements [three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic), | ||
280 | returning [`missing`](@ref) if one operand is `missing` and the other is `true`. | ||
281 | |||
282 | # Examples | ||
283 | ```jldoctest | ||
284 | julia> 4 & 10 | ||
285 | 0 | ||
286 | |||
287 | julia> 4 & 12 | ||
288 | 4 | ||
289 | |||
290 | julia> true & missing | ||
291 | missing | ||
292 | |||
293 | julia> false & missing | ||
294 | false | ||
295 | ``` | ||
296 | """ | ||
297 | (&)(x::T, y::T) where {T<:BitInteger} = and_int(x, y) | ||
298 | |||
299 | """ | ||
300 | |(x, y) | ||
301 | |||
302 | Bitwise or. Implements [three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic), | ||
303 | returning [`missing`](@ref) if one operand is `missing` and the other is `false`. | ||
304 | |||
305 | # Examples | ||
306 | ```jldoctest | ||
307 | julia> 4 | 10 | ||
308 | 14 | ||
309 | |||
310 | julia> 4 | 1 | ||
311 | 5 | ||
312 | |||
313 | julia> true | missing | ||
314 | true | ||
315 | |||
316 | julia> false | missing | ||
317 | missing | ||
318 | ``` | ||
319 | """ | ||
320 | (|)(x::T, y::T) where {T<:BitInteger} = or_int(x, y) | ||
321 | xor(x::T, y::T) where {T<:BitInteger} = xor_int(x, y) | ||
322 | |||
323 | """ | ||
324 | bswap(n) | ||
325 | |||
326 | Reverse the byte order of `n`. | ||
327 | |||
328 | # Examples | ||
329 | ```jldoctest | ||
330 | julia> a = bswap(0x10203040) | ||
331 | 0x40302010 | ||
332 | |||
333 | julia> bswap(a) | ||
334 | 0x10203040 | ||
335 | |||
336 | julia> string(1, base = 2) | ||
337 | "1" | ||
338 | |||
339 | julia> string(bswap(1), base = 2) | ||
340 | "100000000000000000000000000000000000000000000000000000000" | ||
341 | ``` | ||
342 | """ | ||
343 | bswap(x::Union{Int8, UInt8}) = x | ||
344 | bswap(x::Union{Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128}) = | ||
345 | bswap_int(x) | ||
346 | |||
347 | """ | ||
348 | count_ones(x::Integer) -> Integer | ||
349 | |||
350 | Number of ones in the binary representation of `x`. | ||
351 | |||
352 | # Examples | ||
353 | ```jldoctest | ||
354 | julia> count_ones(7) | ||
355 | 3 | ||
356 | ``` | ||
357 | """ | ||
358 | count_ones(x::BitInteger) = Int(ctpop_int(x)) | ||
359 | |||
360 | """ | ||
361 | leading_zeros(x::Integer) -> Integer | ||
362 | |||
363 | Number of zeros leading the binary representation of `x`. | ||
364 | |||
365 | # Examples | ||
366 | ```jldoctest | ||
367 | julia> leading_zeros(Int32(1)) | ||
368 | 31 | ||
369 | ``` | ||
370 | """ | ||
371 | leading_zeros(x::BitInteger) = Int(ctlz_int(x)) | ||
372 | |||
373 | """ | ||
374 | trailing_zeros(x::Integer) -> Integer | ||
375 | |||
376 | Number of zeros trailing the binary representation of `x`. | ||
377 | |||
378 | # Examples | ||
379 | ```jldoctest | ||
380 | julia> trailing_zeros(2) | ||
381 | 1 | ||
382 | ``` | ||
383 | """ | ||
384 | trailing_zeros(x::BitInteger) = Int(cttz_int(x)) | ||
385 | |||
386 | """ | ||
387 | count_zeros(x::Integer) -> Integer | ||
388 | |||
389 | Number of zeros in the binary representation of `x`. | ||
390 | |||
391 | # Examples | ||
392 | ```jldoctest | ||
393 | julia> count_zeros(Int32(2 ^ 16 - 1)) | ||
394 | 16 | ||
395 | ``` | ||
396 | """ | ||
397 | count_zeros(x::Integer) = count_ones(~x) | ||
398 | |||
399 | """ | ||
400 | leading_ones(x::Integer) -> Integer | ||
401 | |||
402 | Number of ones leading the binary representation of `x`. | ||
403 | |||
404 | # Examples | ||
405 | ```jldoctest | ||
406 | julia> leading_ones(UInt32(2 ^ 32 - 2)) | ||
407 | 31 | ||
408 | ``` | ||
409 | """ | ||
410 | leading_ones(x::Integer) = leading_zeros(~x) | ||
411 | |||
412 | """ | ||
413 | trailing_ones(x::Integer) -> Integer | ||
414 | |||
415 | Number of ones trailing the binary representation of `x`. | ||
416 | |||
417 | # Examples | ||
418 | ```jldoctest | ||
419 | julia> trailing_ones(3) | ||
420 | 2 | ||
421 | ``` | ||
422 | """ | ||
423 | trailing_ones(x::Integer) = trailing_zeros(~x) | ||
424 | |||
425 | ## integer comparisons ## | ||
426 | |||
427 | 1 (2.38%) | 1 (2.38%) |
1 (2.38%) samples spent in <
(< )(x::T, y::T) where {T<:BitUnsigned} = ult_int(x, y)
1 (100.00%) (ex.), 1 (100.00%) (incl.) when called from digitgen line 97 |
428 | (<=)(x::T, y::T) where {T<:BitSigned} = sle_int(x, y) | ||
429 | (<=)(x::T, y::T) where {T<:BitUnsigned} = ule_int(x, y) | ||
430 | |||
431 | ==(x::BitSigned, y::BitUnsigned) = (x >= 0) & (unsigned(x) == y) | ||
432 | 1 (2.38%) |
1 (100.00%)
samples spent calling
==
==(x::BitUnsigned, y::BitSigned ) = (y >= 0) & (x == unsigned(y))
|
|
433 | <( x::BitSigned, y::BitUnsigned) = (x < 0) | (unsigned(x) < y) | ||
434 | <( x::BitUnsigned, y::BitSigned ) = (y >= 0) & (x < unsigned(y)) | ||
435 | <=(x::BitSigned, y::BitUnsigned) = (x < 0) | (unsigned(x) <= y) | ||
436 | <=(x::BitUnsigned, y::BitSigned ) = (y >= 0) & (x <= unsigned(y)) | ||
437 | |||
438 | ## integer shifts ## | ||
439 | |||
440 | # unsigned shift counts always shift in the same direction | ||
441 | >>(x::BitSigned, y::BitUnsigned) = ashr_int(x, y) | ||
442 | 1 (2.38%) | 1 (2.38%) | >>(x::BitUnsigned, y::BitUnsigned) = lshr_int(x, y) |
443 | <<(x::BitInteger, y::BitUnsigned) = shl_int(x, y) | ||
444 | >>>(x::BitInteger, y::BitUnsigned) = lshr_int(x, y) | ||
445 | # signed shift counts can shift in either direction | ||
446 | # note: this early during bootstrap, `>=` is not yet available | ||
447 | # note: we only define Int shift counts here; the generic case is handled later | ||
448 | 1 (2.38%) |
1 (100.00%)
samples spent calling
>>
>>(x::BitInteger, y::Int) =
|
|
449 | ifelse(0 <= y, x >> unsigned(y), x << unsigned(-y)) | ||
450 | <<(x::BitInteger, y::Int) = | ||
451 | ifelse(0 <= y, x << unsigned(y), x >> unsigned(-y)) | ||
452 | >>>(x::BitInteger, y::Int) = | ||
453 | ifelse(0 <= y, x >>> unsigned(y), x << unsigned(-y)) | ||
454 | |||
455 | for to in BitInteger_types, from in (BitInteger_types..., Bool) | ||
456 | if !(to === from) | ||
457 | if to.size < from.size | ||
458 | @eval rem(x::($from), ::Type{$to}) = trunc_int($to, x) | ||
459 | elseif from === Bool | ||
460 | @eval rem(x::($from), ::Type{$to}) = convert($to, x) | ||
461 | elseif from.size < to.size | ||
462 | if from <: Signed | ||
463 | @eval rem(x::($from), ::Type{$to}) = sext_int($to, x) | ||
464 | else | ||
465 | @eval rem(x::($from), ::Type{$to}) = convert($to, x) | ||
466 | end | ||
467 | else | ||
468 | @eval rem(x::($from), ::Type{$to}) = bitcast($to, x) | ||
469 | end | ||
470 | end | ||
471 | end | ||
472 | |||
473 | # @doc isn't available when running in Core at this point. | ||
474 | # Tuple syntax for documentation two function signatures at the same time | ||
475 | # doesn't work either at this point. | ||
476 | if nameof(@__MODULE__) === :Base | ||
477 | for fname in (:mod, :rem) | ||
478 | @eval @doc """ | ||
479 | rem(x::Integer, T::Type{<:Integer}) -> T | ||
480 | mod(x::Integer, T::Type{<:Integer}) -> T | ||
481 | %(x::Integer, T::Type{<:Integer}) -> T | ||
482 | |||
483 | Find `y::T` such that `x` ≡ `y` (mod n), where n is the number of integers representable | ||
484 | in `T`, and `y` is an integer in `[typemin(T),typemax(T)]`. | ||
485 | If `T` can represent any integer (e.g. `T == BigInt`), then this operation corresponds to | ||
486 | a conversion to `T`. | ||
487 | |||
488 | # Examples | ||
489 | ```jldoctest | ||
490 | julia> 129 % Int8 | ||
491 | -127 | ||
492 | ``` | ||
493 | """ $fname(x::Integer, T::Type{<:Integer}) | ||
494 | end | ||
495 | end | ||
496 | |||
497 | rem(x::T, ::Type{T}) where {T<:Integer} = x | ||
498 | rem(x::Integer, T::Type{<:Integer}) = convert(T, x) # `x % T` falls back to `convert` | ||
499 | rem(x::Integer, ::Type{Bool}) = ((x & 1) != 0) | ||
500 | mod(x::Integer, ::Type{T}) where {T<:Integer} = rem(x, T) | ||
501 | |||
502 | unsafe_trunc(::Type{T}, x::Integer) where {T<:Integer} = rem(x, T) | ||
503 | |||
504 | """ | ||
505 | trunc([T,] x) | ||
506 | trunc(x; digits::Integer= [, base = 10]) | ||
507 | trunc(x; sigdigits::Integer= [, base = 10]) | ||
508 | |||
509 | `trunc(x)` returns the nearest integral value of the same type as `x` whose absolute value | ||
510 | is less than or equal to `x`. | ||
511 | |||
512 | `trunc(T, x)` converts the result to type `T`, throwing an `InexactError` if the value is | ||
513 | not representable. | ||
514 | |||
515 | `digits`, `sigdigits` and `base` work as for [`round`](@ref). | ||
516 | """ | ||
517 | function trunc end | ||
518 | |||
519 | """ | ||
520 | floor([T,] x) | ||
521 | floor(x; digits::Integer= [, base = 10]) | ||
522 | floor(x; sigdigits::Integer= [, base = 10]) | ||
523 | |||
524 | `floor(x)` returns the nearest integral value of the same type as `x` that is less than or | ||
525 | equal to `x`. | ||
526 | |||
527 | `floor(T, x)` converts the result to type `T`, throwing an `InexactError` if the value is | ||
528 | not representable. | ||
529 | |||
530 | `digits`, `sigdigits` and `base` work as for [`round`](@ref). | ||
531 | """ | ||
532 | function floor end | ||
533 | |||
534 | """ | ||
535 | ceil([T,] x) | ||
536 | ceil(x; digits::Integer= [, base = 10]) | ||
537 | ceil(x; sigdigits::Integer= [, base = 10]) | ||
538 | |||
539 | `ceil(x)` returns the nearest integral value of the same type as `x` that is greater than or | ||
540 | equal to `x`. | ||
541 | |||
542 | `ceil(T, x)` converts the result to type `T`, throwing an `InexactError` if the value is not | ||
543 | representable. | ||
544 | |||
545 | `digits`, `sigdigits` and `base` work as for [`round`](@ref). | ||
546 | """ | ||
547 | function ceil end | ||
548 | |||
549 | round(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) | ||
550 | trunc(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) | ||
551 | floor(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) | ||
552 | ceil(::Type{T}, x::Integer) where {T<:Integer} = convert(T, x) | ||
553 | |||
554 | ## integer construction ## | ||
555 | |||
556 | """ | ||
557 | @int128_str str | ||
558 | @int128_str(str) | ||
559 | |||
560 | `@int128_str` parses a string into a Int128 | ||
561 | Throws an `ArgumentError` if the string is not a valid integer | ||
562 | """ | ||
563 | macro int128_str(s) | ||
564 | return parse(Int128, s) | ||
565 | end | ||
566 | |||
567 | """ | ||
568 | @uint128_str str | ||
569 | @uint128_str(str) | ||
570 | |||
571 | `@uint128_str` parses a string into a UInt128 | ||
572 | Throws an `ArgumentError` if the string is not a valid integer | ||
573 | """ | ||
574 | macro uint128_str(s) | ||
575 | return parse(UInt128, s) | ||
576 | end | ||
577 | |||
578 | """ | ||
579 | @big_str str | ||
580 | @big_str(str) | ||
581 | |||
582 | Parse a string into a [`BigInt`](@ref) or [`BigFloat`](@ref), | ||
583 | and throw an `ArgumentError` if the string is not a valid number. | ||
584 | For integers `_` is allowed in the string as a separator. | ||
585 | |||
586 | # Examples | ||
587 | ```jldoctest | ||
588 | julia> big"123_456" | ||
589 | 123456 | ||
590 | |||
591 | julia> big"7891.5" | ||
592 | 7.8915e+03 | ||
593 | ``` | ||
594 | """ | ||
595 | macro big_str(s) | ||
596 | if '_' in s | ||
597 | # remove _ in s[2:end-1] | ||
598 | bf = IOBuffer(maxsize=lastindex(s)) | ||
599 | print(bf, s[1]) | ||
600 | for c in SubString(s, 2, lastindex(s)-1) | ||
601 | c != '_' && print(bf, c) | ||
602 | end | ||
603 | print(bf, s[end]) | ||
604 | seekstart(bf) | ||
605 | n = tryparse(BigInt, String(take!(bf))) | ||
606 | n === nothing || return n | ||
607 | else | ||
608 | n = tryparse(BigInt, s) | ||
609 | n === nothing || return n | ||
610 | n = tryparse(BigFloat, s) | ||
611 | n === nothing || return n | ||
612 | end | ||
613 | message = "invalid number format $s for BigInt or BigFloat" | ||
614 | return :(throw(ArgumentError($message))) | ||
615 | end | ||
616 | |||
617 | ## integer promotions ## | ||
618 | |||
619 | # with different sizes, promote to larger type | ||
620 | promote_rule(::Type{Int16}, ::Union{Type{Int8}, Type{UInt8}}) = Int16 | ||
621 | promote_rule(::Type{Int32}, ::Union{Type{Int16}, Type{Int8}, Type{UInt16}, Type{UInt8}}) = Int32 | ||
622 | promote_rule(::Type{Int64}, ::Union{Type{Int16}, Type{Int32}, Type{Int8}, Type{UInt16}, Type{UInt32}, Type{UInt8}}) = Int64 | ||
623 | promote_rule(::Type{Int128}, ::Union{Type{Int16}, Type{Int32}, Type{Int64}, Type{Int8}, Type{UInt16}, Type{UInt32}, Type{UInt64}, Type{UInt8}}) = Int128 | ||
624 | promote_rule(::Type{UInt16}, ::Union{Type{Int8}, Type{UInt8}}) = UInt16 | ||
625 | promote_rule(::Type{UInt32}, ::Union{Type{Int16}, Type{Int8}, Type{UInt16}, Type{UInt8}}) = UInt32 | ||
626 | promote_rule(::Type{UInt64}, ::Union{Type{Int16}, Type{Int32}, Type{Int8}, Type{UInt16}, Type{UInt32}, Type{UInt8}}) = UInt64 | ||
627 | promote_rule(::Type{UInt128}, ::Union{Type{Int16}, Type{Int32}, Type{Int64}, Type{Int8}, Type{UInt16}, Type{UInt32}, Type{UInt64}, Type{UInt8}}) = UInt128 | ||
628 | # with mixed signedness and same size, Unsigned wins | ||
629 | promote_rule(::Type{UInt8}, ::Type{Int8} ) = UInt8 | ||
630 | promote_rule(::Type{UInt16}, ::Type{Int16} ) = UInt16 | ||
631 | promote_rule(::Type{UInt32}, ::Type{Int32} ) = UInt32 | ||
632 | promote_rule(::Type{UInt64}, ::Type{Int64} ) = UInt64 | ||
633 | promote_rule(::Type{UInt128}, ::Type{Int128}) = UInt128 | ||
634 | |||
635 | _default_type(::Type{Unsigned}) = UInt | ||
636 | _default_type(::Union{Type{Integer},Type{Signed}}) = Int | ||
637 | |||
638 | ## traits ## | ||
639 | |||
640 | """ | ||
641 | typemin(T) | ||
642 | |||
643 | The lowest value representable by the given (real) numeric DataType `T`. | ||
644 | |||
645 | # Examples | ||
646 | ```jldoctest | ||
647 | julia> typemin(Float16) | ||
648 | -Inf16 | ||
649 | |||
650 | julia> typemin(Float32) | ||
651 | -Inf32 | ||
652 | ``` | ||
653 | """ | ||
654 | function typemin end | ||
655 | |||
656 | """ | ||
657 | typemax(T) | ||
658 | |||
659 | The highest value representable by the given (real) numeric `DataType`. | ||
660 | |||
661 | # Examples | ||
662 | ```jldoctest | ||
663 | julia> typemax(Int8) | ||
664 | 127 | ||
665 | |||
666 | julia> typemax(UInt32) | ||
667 | 0xffffffff | ||
668 | ``` | ||
669 | """ | ||
670 | function typemax end | ||
671 | |||
672 | typemin(::Type{Int8 }) = Int8(-128) | ||
673 | typemax(::Type{Int8 }) = Int8(127) | ||
674 | typemin(::Type{UInt8 }) = UInt8(0) | ||
675 | typemax(::Type{UInt8 }) = UInt8(255) | ||
676 | typemin(::Type{Int16 }) = Int16(-32768) | ||
677 | typemax(::Type{Int16 }) = Int16(32767) | ||
678 | typemin(::Type{UInt16}) = UInt16(0) | ||
679 | typemax(::Type{UInt16}) = UInt16(65535) | ||
680 | typemin(::Type{Int32 }) = Int32(-2147483648) | ||
681 | typemax(::Type{Int32 }) = Int32(2147483647) | ||
682 | typemin(::Type{UInt32}) = UInt32(0) | ||
683 | typemax(::Type{UInt32}) = UInt32(4294967295) | ||
684 | typemin(::Type{Int64 }) = -9223372036854775808 | ||
685 | typemax(::Type{Int64 }) = 9223372036854775807 | ||
686 | typemin(::Type{UInt64}) = UInt64(0) | ||
687 | typemax(::Type{UInt64}) = 0xffffffffffffffff | ||
688 | @eval typemin(::Type{UInt128}) = $(convert(UInt128, 0)) | ||
689 | @eval typemax(::Type{UInt128}) = $(bitcast(UInt128, convert(Int128, -1))) | ||
690 | @eval typemin(::Type{Int128} ) = $(convert(Int128, 1) << 127) | ||
691 | @eval typemax(::Type{Int128} ) = $(bitcast(Int128, typemax(UInt128) >> 1)) | ||
692 | |||
693 | |||
694 | widen(::Type{Int8}) = Int16 | ||
695 | widen(::Type{Int16}) = Int32 | ||
696 | widen(::Type{Int32}) = Int64 | ||
697 | widen(::Type{Int64}) = Int128 | ||
698 | widen(::Type{UInt8}) = UInt16 | ||
699 | widen(::Type{UInt16}) = UInt32 | ||
700 | widen(::Type{UInt32}) = UInt64 | ||
701 | widen(::Type{UInt64}) = UInt128 | ||
702 | |||
703 | # a few special cases, | ||
704 | # Int64*UInt64 => Int128 | ||
705 | # |x|<=2^(k-1), |y|<=2^k-1 => |x*y|<=2^(2k-1)-1 | ||
706 | widemul(x::Signed,y::Unsigned) = widen(x) * signed(widen(y)) | ||
707 | widemul(x::Unsigned,y::Signed) = signed(widen(x)) * widen(y) | ||
708 | # multplication by Bool doesn't require widening | ||
709 | widemul(x::Bool,y::Bool) = x * y | ||
710 | widemul(x::Bool,y::Number) = x * y | ||
711 | widemul(x::Number,y::Bool) = x * y | ||
712 | |||
713 | |||
714 | ## wide multiplication, Int128 multiply and divide ## | ||
715 | |||
716 | if Core.sizeof(Int) == 4 | ||
717 | function widemul(u::Int64, v::Int64) | ||
718 | local u0::UInt64, v0::UInt64, w0::UInt64 | ||
719 | local u1::Int64, v1::Int64, w1::UInt64, w2::Int64, t::UInt64 | ||
720 | |||
721 | u0 = u & 0xffffffff; u1 = u >> 32 | ||
722 | v0 = v & 0xffffffff; v1 = v >> 32 | ||
723 | w0 = u0 * v0 | ||
724 | t = reinterpret(UInt64, u1) * v0 + (w0 >>> 32) | ||
725 | w2 = reinterpret(Int64, t) >> 32 | ||
726 | w1 = u0 * reinterpret(UInt64, v1) + (t & 0xffffffff) | ||
727 | hi = u1 * v1 + w2 + (reinterpret(Int64, w1) >> 32) | ||
728 | lo = w0 & 0xffffffff + (w1 << 32) | ||
729 | return Int128(hi) << 64 + Int128(lo) | ||
730 | end | ||
731 | |||
732 | function widemul(u::UInt64, v::UInt64) | ||
733 | local u0::UInt64, v0::UInt64, w0::UInt64 | ||
734 | local u1::UInt64, v1::UInt64, w1::UInt64, w2::UInt64, t::UInt64 | ||
735 | |||
736 | u0 = u & 0xffffffff; u1 = u >>> 32 | ||
737 | v0 = v & 0xffffffff; v1 = v >>> 32 | ||
738 | w0 = u0 * v0 | ||
739 | t = u1 * v0 + (w0 >>> 32) | ||
740 | w2 = t >>> 32 | ||
741 | w1 = u0 * v1 + (t & 0xffffffff) | ||
742 | hi = u1 * v1 + w2 + (w1 >>> 32) | ||
743 | lo = w0 & 0xffffffff + (w1 << 32) | ||
744 | return UInt128(hi) << 64 + UInt128(lo) | ||
745 | end | ||
746 | |||
747 | function *(u::Int128, v::Int128) | ||
748 | u0 = u % UInt64; u1 = Int64(u >> 64) | ||
749 | v0 = v % UInt64; v1 = Int64(v >> 64) | ||
750 | lolo = widemul(u0, v0) | ||
751 | lohi = widemul(reinterpret(Int64, u0), v1) | ||
752 | hilo = widemul(u1, reinterpret(Int64, v0)) | ||
753 | t = reinterpret(UInt128, hilo) + (lolo >>> 64) | ||
754 | w1 = reinterpret(UInt128, lohi) + (t & 0xffffffffffffffff) | ||
755 | return Int128(lolo & 0xffffffffffffffff) + reinterpret(Int128, w1) << 64 | ||
756 | end | ||
757 | |||
758 | function *(u::UInt128, v::UInt128) | ||
759 | u0 = u % UInt64; u1 = UInt64(u>>>64) | ||
760 | v0 = v % UInt64; v1 = UInt64(v>>>64) | ||
761 | lolo = widemul(u0, v0) | ||
762 | lohi = widemul(u0, v1) | ||
763 | hilo = widemul(u1, v0) | ||
764 | t = hilo + (lolo >>> 64) | ||
765 | w1 = lohi + (t & 0xffffffffffffffff) | ||
766 | return (lolo & 0xffffffffffffffff) + UInt128(w1) << 64 | ||
767 | end | ||
768 | |||
769 | function div(x::Int128, y::Int128) | ||
770 | (x == typemin(Int128)) & (y == -1) && throw(DivideError()) | ||
771 | return Int128(div(BigInt(x), BigInt(y))) | ||
772 | end | ||
773 | function div(x::UInt128, y::UInt128) | ||
774 | return UInt128(div(BigInt(x), BigInt(y)))::UInt128 | ||
775 | end | ||
776 | |||
777 | function rem(x::Int128, y::Int128) | ||
778 | return Int128(rem(BigInt(x), BigInt(y))) | ||
779 | end | ||
780 | function rem(x::UInt128, y::UInt128) | ||
781 | return UInt128(rem(BigInt(x), BigInt(y))) | ||
782 | end | ||
783 | |||
784 | function mod(x::Int128, y::Int128) | ||
785 | return Int128(mod(BigInt(x), BigInt(y))) | ||
786 | end | ||
787 | else | ||
788 | *(x::T, y::T) where {T<:Union{Int128,UInt128}} = mul_int(x, y) | ||
789 | |||
790 | div(x::Int128, y::Int128) = checked_sdiv_int(x, y) | ||
791 | div(x::UInt128, y::UInt128) = checked_udiv_int(x, y) | ||
792 | |||
793 | rem(x::Int128, y::Int128) = checked_srem_int(x, y) | ||
794 | rem(x::UInt128, y::UInt128) = checked_urem_int(x, y) | ||
795 | end | ||
796 | |||
797 | # issue #15489: since integer ops are unchecked, they shouldn't check promotion | ||
798 | for op in (:+, :-, :*, :&, :|, :xor) | ||
799 | @eval function $op(a::Integer, b::Integer) | ||
800 | T = promote_typeof(a, b) | ||
801 | aT, bT = a % T, b % T | ||
802 | not_sametype((a, b), (aT, bT)) | ||
803 | 1 (2.38%) |
1 (100.00%)
samples spent calling
+
return $op(aT, bT)
|
|
804 | end | ||
805 | end |