microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/3208-leak-fixes

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

library/std/src/Std/Convert.qs

326lines · modecode

1import Std.Diagnostics.*;
2import Std.Math.*;
3
4/// # Summary
5/// Converts a given integer `number` to an equivalent
6/// double-precision floating-point number.
7///
8/// # Description
9/// Converts a given integer to a double-precision floating point number.
10/// Please note that the double-precision representation may have fewer
11/// bits allocated to represent [significant digits](https://en.wikipedia.org/wiki/Significand)
12/// so the conversion may be approximate for large numbers. For example,
13/// the current simulator converts 4,611,686,018,427,387,919 = 2^64+15
14/// to 4,611,686,018,427,387,904.0 = 2^64.
15///
16/// # Example
17/// ```qsharp
18/// Message($"{IntAsDouble(1)}"); // Prints 1.0 rather than 1
19/// ```
20function IntAsDouble(number : Int) : Double {
21 body intrinsic;
22}
23
24/// # Summary
25/// Converts a given integer `number` to an equivalent big integer.
26function IntAsBigInt(number : Int) : BigInt {
27 body intrinsic;
28}
29
30/// # Summary
31/// Converts a `Result` type to a `Bool` type, where `One` is mapped to
32/// `true` and `Zero` is mapped to `false`.
33///
34/// # Input
35/// ## input
36/// `Result` to be converted.
37///
38/// # Output
39/// A `Bool` representing the `input`.
40function ResultAsBool(input : Result) : Bool {
41 input == One
42}
43
44/// # Summary
45/// Converts a `Bool` type to a `Result` type, where `true` is mapped to
46/// `One` and `false` is mapped to `Zero`.
47///
48/// # Input
49/// ## input
50/// `Bool` to be converted.
51///
52/// # Output
53/// A `Result` representing the `input`.
54function BoolAsResult(input : Bool) : Result {
55 if input { One } else { Zero }
56}
57
58/// # Summary
59/// Produces a non-negative integer from a string of bits in little-endian format.
60/// `bits[0]` represents the least significant bit.
61///
62/// # Input
63/// ## bits
64/// Bits in binary representation of number.
65function BoolArrayAsInt(bits : Bool[]) : Int {
66 let nBits = Length(bits);
67 Fact(nBits < 64, $"`Length(bits)` must be less than 64, but was {nBits}.");
68
69 mutable number = 0;
70 for i in 0..nBits - 1 {
71 if (bits[i]) {
72 set number |||= 1 <<< i;
73 }
74 }
75
76 number
77}
78
79/// # Summary
80/// Produces a binary representation of a non-negative integer, using the
81/// little-endian representation for the returned array.
82///
83/// # Input
84/// ## number
85/// A non-negative integer to be converted to an array of Boolean values.
86/// ## bits
87/// The number of bits in the binary representation of `number`.
88///
89/// # Output
90/// An array of Boolean values representing `number`.
91///
92/// # Remarks
93/// The input `bits` must be non-negative.
94/// The input `number` must be between 0 and 2^bits - 1.
95function IntAsBoolArray(number : Int, bits : Int) : Bool[] {
96 Fact(bits >= 0, "Requested number of bits must be non-negative.");
97 Fact(number >= 0, "Number must be non-negative.");
98 mutable runningValue = number;
99 mutable result = [];
100 for _ in 1..bits {
101 set result += [(runningValue &&& 1) != 0];
102 set runningValue >>>= 1;
103 }
104 Fact(runningValue == 0, "`number` is too large to fit into array of length `bits`.");
105
106 result
107}
108
109/// # Summary
110/// Converts an array of Boolean values into a non-negative BigInt, interpreting the
111/// array as a binary representation in little-endian format.
112///
113/// # Input
114/// ## boolArray
115/// An array of Boolean values representing the binary digits of a BigInt.
116///
117/// # Output
118/// A BigInt represented by `boolArray`.
119///
120/// # Remarks
121/// The function interprets the array in little-endian format, where the first
122/// element of the array represents the least significant bit.
123/// The input `boolArray` should not be empty.
124function BoolArrayAsBigInt(boolArray : Bool[]) : BigInt {
125 mutable result = 0L;
126 for i in 0..Length(boolArray) - 1 {
127 if boolArray[i] {
128 set result += 1L <<< i;
129 }
130 }
131
132 result
133}
134
135/// # Summary
136/// Produces a binary representation of a non-negative BigInt, using the
137/// little-endian representation for the returned array.
138///
139/// # Input
140/// ## number
141/// A non-negative BigInt to be converted to an array of Boolean values.
142/// ## bits
143/// The number of bits in the binary representation of `number`.
144///
145/// # Output
146/// An array of Boolean values representing `number`.
147///
148/// # Remarks
149/// The input `bits` must be non-negative.
150/// The input `number` must be between 0 and 2^bits - 1.
151function BigIntAsBoolArray(number : BigInt, bits : Int) : Bool[] {
152 Fact(bits >= 0, "Requested number of bits must be non-negative.");
153 Fact(number >= 0L, "Number must be non-negative.");
154 mutable runningValue = number;
155 mutable result = [];
156 for _ in 1..bits {
157 set result += [(runningValue &&& 1L) != 0L];
158 set runningValue >>>= 1;
159 }
160 Fact(runningValue == 0L, $"`number`={number} is too large to fit into {bits} bits.");
161
162 result
163}
164
165/// # Summary
166/// Converts a BigInt number into Int. Raises an error if the number is too large to fit.
167///
168/// # Input
169/// ## number
170/// A BigInt number to be converted.
171///
172/// # Output
173/// Int representation of a number.
174function BigIntAsInt(number : BigInt) : Int {
175 let max = 9_223_372_036_854_775_807L;
176 let min = -9_223_372_036_854_775_808L;
177 Fact(number >= min and number <= max, $"BigIntAsInt: {number} is too big to fit into Int.");
178
179 mutable result = 0;
180 mutable powL = 1L;
181 mutable pow = 1;
182 for _ in 0..63 {
183 if number &&& powL != 0L {
184 result |||= pow;
185 }
186 powL <<<= 1;
187 pow <<<= 1;
188 }
189
190 result
191}
192
193/// # Summary
194/// Produces a non-negative integer from a string of Results in little-endian format.
195///
196/// # Input
197/// ## results
198/// Results in binary representation of number.
199///
200/// # Output
201/// A non-negative integer
202///
203/// # Example
204/// ```qsharp
205/// // The following returns 1
206/// let int1 = ResultArrayAsInt([One,Zero])
207/// ```
208function ResultArrayAsInt(results : Result[]) : Int {
209 let nBits = Length(results);
210 Fact(nBits < 64, $"`Length(bits)` must be less than 64, but was {nBits}.");
211
212 mutable number = 0;
213 for idxBit in 0..nBits - 1 {
214 if (results[idxBit] == One) {
215 set number |||= 1 <<< idxBit;
216 }
217 }
218
219 number
220}
221
222/// # Summary
223/// Converts a `Result[]` type to a `Bool[]` type, where `One`
224/// is mapped to `true` and `Zero` is mapped to `false`.
225///
226/// # Input
227/// ## input
228/// `Result[]` to be converted.
229///
230/// # Output
231/// A `Bool[]` representing the `input`.
232function ResultArrayAsBoolArray(input : Result[]) : Bool[] {
233 mutable output = [];
234 for r in input {
235 set output += [r == One];
236 }
237
238 output
239}
240
241/// # Summary
242/// Converts a `Bool[]` type to a `Result[]` type, where `true`
243/// is mapped to `One` and `false` is mapped to `Zero`.
244///
245/// # Input
246/// ## input
247/// `Bool[]` to be converted.
248///
249/// # Output
250/// A `Result[]` representing the `input`.
251function BoolArrayAsResultArray(input : Bool[]) : Result[] {
252 mutable output = [];
253 for b in input {
254 set output += [if b { One } else { Zero }];
255 }
256
257 output
258}
259
260/// # Summary
261/// Converts a complex number of type `Complex` to a complex
262/// number of type `ComplexPolar`.
263///
264/// # Input
265/// ## input
266/// Complex number c = x + y𝑖.
267///
268/// # Output
269/// Complex number c = r⋅e^(t𝑖).
270function ComplexAsComplexPolar(input : Complex) : ComplexPolar {
271 return ComplexPolar(AbsComplex(input), ArgComplex(input));
272}
273
274/// # Summary
275/// Converts a complex number of type `ComplexPolar` to a complex
276/// number of type `Complex`.
277///
278/// # Input
279/// ## input
280/// Complex number c = r⋅e^(t𝑖).
281///
282/// # Output
283/// Complex number c = x + y𝑖.
284function ComplexPolarAsComplex(input : ComplexPolar) : Complex {
285 return Complex(
286 input.Magnitude * Cos(input.Argument),
287 input.Magnitude * Sin(input.Argument)
288 );
289}
290
291/// # Summary
292/// Converts a given double-precision floating-point number to a string representation with desired precision, rounding if required.
293///
294/// # Input
295/// ## input
296/// Double to be converted.
297/// ## precision
298/// Non-negative number of digits after the decimal point.
299///
300/// # Example
301/// ```qsharp
302/// Message($"{DoubleAsStringWithPrecision(0.354, 2)}"); // Prints 0.35
303/// Message($"{DoubleAsStringWithPrecision(0.485, 1)}"); // Prints 0.5
304/// Message($"{DoubleAsStringWithPrecision(5.6, 4)}"); // Prints 5.6000
305/// Message($"{DoubleAsStringWithPrecision(2.268, 0)}"); // Prints 2
306/// ```
307function DoubleAsStringWithPrecision(input : Double, precision : Int) : String {
308 body intrinsic;
309}
310
311export
312 IntAsDouble,
313 IntAsBigInt,
314 ResultAsBool,
315 BoolAsResult,
316 BoolArrayAsInt,
317 IntAsBoolArray,
318 BoolArrayAsBigInt,
319 BigIntAsBoolArray,
320 BigIntAsInt,
321 ResultArrayAsInt,
322 ResultArrayAsBoolArray,
323 BoolArrayAsResultArray,
324 ComplexAsComplexPolar,
325 ComplexPolarAsComplex,
326 DoubleAsStringWithPrecision;
327