microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
8a151f109cece83aeea78e74d62cd6f25e7996a3

Branches

Tags

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

Clone

HTTPS

Download ZIP

library/fixed_point/src/Convert.qs

95lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4import Std.Convert.IntAsDouble, Std.Convert.BoolArrayAsInt;
5import Std.Math.AbsD, Std.Math.Floor;
6import Std.Arrays.Most, Std.Arrays.Tail;
7
8/// # Summary
9/// Computes fixed-point approximation for a double and returns it as `Bool` array.
10///
11/// # Input
12/// ## integerBits
13/// Assumed number of integer bits (including the sign bit).
14/// ## fractionalBits
15/// Assumed number of fractional bits.
16/// ## value
17/// Value to be approximated.
18///
19/// # Example
20/// Note that the first element in the Boolean array is the least-significant bit.
21/// ```qsharp
22/// let bits = FixedPointAsBoolArray(2, 2, 1.25); // bits = [true, false, true, false]
23/// let bits = FixedPointAsBoolArray(2, 2, 1.3); // bits = [true, false, true, false], approximated
24/// let bits = FixedPointAsBoolArray(2, 2, -1.75); // bits = [true, false, false, true], two's complement
25/// ```
26function FixedPointAsBoolArray(integerBits : Int, fractionalBits : Int, value : Double) : Bool[] {
27 let numBits = integerBits + fractionalBits;
28 let sign = value < 0.0;
29
30 mutable result = [false, size = numBits];
31 mutable rescaledConstant = 2.0^IntAsDouble(fractionalBits) * AbsD(value) + 0.5;
32 mutable keepAdding = sign;
33
34 for idx in 0..numBits - 1 {
35 let intConstant = Floor(rescaledConstant);
36 set rescaledConstant = rescaledConstant / 2.0;
37 mutable currentBit = (intConstant &&& 1) == (sign ? 0 | 1);
38 if keepAdding {
39 set keepAdding = currentBit;
40 set currentBit = not currentBit;
41 }
42 if currentBit {
43 set result w/= idx <- true;
44 }
45 }
46
47 return result;
48}
49
50/// # Summary
51/// Returns the double value of a fixed-point approximation from of a `Bool` array.
52///
53/// # Input
54/// ## integerBits
55/// Assumed number of integer bits (including the sign bit).
56/// ## bits
57/// Bit-string representation of approximated number.
58///
59/// # Example
60/// Note that the first element in the Boolean array is the least-significant bit.
61/// ```qsharp
62/// let value = BoolArrayAsFixedPoint(2, [true, false, true, false]); // value = 1.25
63/// let value = BoolArrayAsFixedPoint(2, [true, false, false, true]); // value = -1.75
64/// ```
65
66function BoolArrayAsFixedPoint(integerBits : Int, bits : Bool[]) : Double {
67 let numBits = Length(bits);
68 let intPart = (Tail(bits) ? -(1 <<< (numBits - 1)) | 0) + BoolArrayAsInt(Most(bits));
69 return IntAsDouble(intPart) / (2.0^IntAsDouble(numBits - integerBits));
70}
71
72/// # Summary
73/// Discretizes a double value as a fixed-point approximation and returns its value as a double.
74///
75/// # Input
76/// ## integerBits
77/// Assumed number of integer bits (including the sign bit).
78/// ## fractionalBits
79/// Assumed number of fractional bits.
80/// ## value
81/// Value to be approximated.
82///
83/// # Example
84/// ```qsharp
85/// let value = DoubleAsFixedPoint(2, 2, 1.3); // value = 1.25
86/// let value = DoubleAsFixedPoint(2, 2, 0.8); // value = 0.75
87/// ```
88function DoubleAsFixedPoint(integerBits : Int, fractionalBits : Int, value : Double) : Double {
89 return BoolArrayAsFixedPoint(integerBits, FixedPointAsBoolArray(integerBits, fractionalBits, value));
90}
91
92export
93 FixedPointAsBoolArray,
94 BoolArrayAsFixedPoint,
95 DoubleAsFixedPoint;