microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
library/std/src/Std/Convert.qs
326lines · modecode
| 1 | import Std.Diagnostics.*; |
| 2 | import 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 | /// ``` |
| 20 | function IntAsDouble(number : Int) : Double { |
| 21 | body intrinsic; |
| 22 | } |
| 23 | |
| 24 | /// # Summary |
| 25 | /// Converts a given integer `number` to an equivalent big integer. |
| 26 | function 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`. |
| 40 | function 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`. |
| 54 | function 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. |
| 65 | function 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. |
| 95 | function 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. |
| 124 | function 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. |
| 151 | function 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. |
| 174 | function 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 | /// ``` |
| 208 | function 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`. |
| 232 | function 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`. |
| 251 | function 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𝑖). |
| 270 | function 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𝑖. |
| 284 | function 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 | /// ``` |
| 307 | function DoubleAsStringWithPrecision(input : Double, precision : Int) : String { |
| 308 | body intrinsic; |
| 309 | } |
| 310 | |
| 311 | export |
| 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 | |