// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import Std.Diagnostics.Fact;
import Operations.Invert2sSI;
/// # Summary
/// Measures a signed integer of a given width.
/// If the width is 4, the qubit register will be measured as a 4-bit signed integer.
/// This means that bit n is the sign bit, and bits n-1 to 0 are the integer value.
/// If fewer than `width` qubits are provided, the remaining bits are assumed to be 0.
/// For example, if qubit register `[q1, q2, q3]` is passed in, but the width is 5,
/// the integer value will be measured as `[0, 0, q1, q2, q3]`, with the first 0 being
/// the sign bit (positive). This is in contrast to the standard library `MeasureInteger`,
/// which always measures unsigned integers up to and including 63 qubits in width.
/// If the length of the qubit register passed in is greater than the width, this operation
/// will throw an error.
///
/// # Input
/// ## target
/// A qubit register representing the signed integer to be measured.
///
/// ## width
/// The width of the signed integer to be measured.
operation MeasureSignedInteger(target : Qubit[], width : Int) : Int {
let nBits = Length(target);
Fact(nBits <= 64, $"`Length(target)` must be less than or equal to 64, but was {nBits}.");
Fact(nBits <= width, $"`Length(target)` must be less than or equal to `width`, but was {nBits}.");
Fact(nBits > 0, $"`width` must be greater than 0, but was {width}.");
mutable coefficient = 1;
let signBit = MResetZ(target[nBits - 1]);
if (signBit == One) {
Operations.Invert2sSI(target);
set coefficient = -1;
}
mutable number = 0;
for i in 0..nBits - 2 {
if (MResetZ(target[i]) == One) {
set number |||= 1 <<< i;
}
}
ResetAll(target);
number * coefficient
}
export MeasureSignedInteger;microsoft/qdk
Publicmirrored from https://github.com/microsoft/qdkAvailable
library/signed/src/Measurement.qs
50lines · modepreview