/usr/include/itpp/fixed/fix_base.h is in libitpp-dev 4.3.1-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | /*!
* \file
* \brief Definitions of a base class for fixed-point data types
* \author Johan Bergman
*
* -------------------------------------------------------------------------
*
* Copyright (C) 1995-2010 (see AUTHORS file for a list of contributors)
*
* This file is part of IT++ - a C++ library of mathematical, signal
* processing, speech processing, and communications classes and functions.
*
* IT++ is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* IT++ is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with IT++. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef FIX_BASE_H
#define FIX_BASE_H
#include <itpp/base/ittypes.h>
#include <itpp/stat/misc_stat.h>
#include <itpp/itexports.h>
namespace itpp
{
/*!
\addtogroup fixed
\brief Fixed-Point Data Types
\author Johan Bergman
\section fix_contents Contents
<ul>
<li> \ref fix_intro
<li> \ref fix_base
<ul>
<li> \ref fix_base_shift
<li> \ref fix_base_wordlen
<li> \ref fix_base_emode
<li> \ref fix_base_omode
<li> \ref fix_base_qmode
<li> \ref fix_base_stat
<li> \ref fix_base_outputmode
</ul>
<li> \ref fix_real
<li> \ref fix_complex
<li> \ref fix_factory
<li> \ref fix_ops
<ul>
<li> \ref fix_ops_asn
<li> \ref fix_ops_add
<li> \ref fix_ops_mult
<li> \ref fix_ops_shift
<li> \ref fix_ops_conv
<li> \ref fix_ops_get
<li> \ref fix_ops_io
</ul>
<li> \ref fix_fcn
<ul>
<li> \ref fix_fcn_isfix
<li> \ref fix_fcn_setfix
<li> \ref fix_fcn_shiftfix
<li> \ref fix_fcn_assert
<li> \ref fix_fcn_unfix
<li> \ref fix_fcn_to
<li> \ref fix_fcn_other
</ul>
</ul>
\section fix_intro Introduction
How to include the support for fixed-point data types in your program:
\code
#include <itpp/itbase.h>
#include <itpp/itfixed.h>
using namespace itpp;
\endcode
Fixed-point data types in IT++:
<ul>
<li> itpp::Fix (real-valued, restrictions specified as constructor arguments)
<li> itpp::Fixed (real-valued, restrictions specified as template arguments)
<li> itpp::CFix (complex-valued, restrictions specified as constructor arguments)
<li> itpp::CFixed (complex-valued, restrictions specified as template arguments)
</ul>
These classes have a common base class called Fix_Base; see inheritance
diagram in the itpp::Fix_Base documentation. The following data members are
inherited from Fix_Base:
<ul>
<li> Shift factor
<li> Word length
<li> Sign encoding mode
<li> Overflow mode
<li> Quantization mode
<li> Statistics object pointer
<li> Output mode
</ul>
The term "fixed-point restrictions" refers to all these data members except
for the shift factor, which is considered to be part of the "fixed-point
number". The shift factor has some resemblance to a binary point. The value of
the shift factor is set in initializations and assignments and it is modified
by multiplications, divisions and bit-shifting operations. The shift factor is
used for checking that both terms have been shifted the same amount in
additions and subtractions. Also, it is used to "un-shift" the data when a
fixed-point number is converted to floating point.
Names of classes and enums have been aligned with the fixed-point data types
in SystemC to some extent, but the fixed-point data types in IT++ and SystemC
are quite different. In fact, the fixed-point data types in IT++ probably
correspond better to the variable-precision integer types in SystemC (with
one important difference: the fixed-point numbers in IT++ remember the amount
of bit-shifting that has been applied to them, so that they can be converted
back to "floating-point magnitude" easily if this is desired). The reason for
this design choice in IT++ is to make the fixed-point simulations as fast as
possible. If necessary, the core parts in itbase.h (e.g. Array, Vec and Mat)
should be able to use some other data type than the ones presented here,
assuming that a proper itpp::Factory is created for the data type, just like
itpp::Fix_Factory has been created for these data types.
Sometimes the documentation for the IT++ fixed-point data types states that
a function is "useful in templated code". This means that the function
facilitates writing templated code where the template argument is meant to be
either a floating-point type (double or complex<double>) or a fixed-point type
(Fix or CFix), i.e. code which is supposed to support both floating-point and
fixed-point simulations. For example, the operator >>= is defined for Fix and
CFix, but not for double and complex<double>, so it might be a better idea to
use the function rshift_fix which is defined for Fix and CFix as well as
double and complex<double>.
For an example program, take a look at tests/fix_test.cpp.
\section fix_base Fix_Base
\subsection fix_base_shift Shift factor
Supported shift factors: -64 ... +63 bit-shifts. 0 is \e default.
An IT++ fixed-point number consists of a bit representation and a shift
factor. The shift factor is a member of Fix_Base, while the bit representation
is a member of the inherited class (Fix or CFix). The shift factor indicates
the number of bit-shifts that have been performed on the data. A positive
shift factor means that the data has been left-shifted while a negative shift
factor means that the data has been right-shifted. For information about how
the shift factor is affected by different operators, see section \ref fix_ops.
\subsection fix_base_wordlen Word length
Supported word lengths: 1 ... 64 bits. 64 is \e default.
\warning Fix, Fixed, CFix and CFixed always use \e signed 64-bit integers to
represent the fixed-point data. Therefore it is not recommended to declare
variables with 64 bits and sign encoding mode US.
\subsection fix_base_emode Sign encoding mode
Supported sign encoding modes (itpp::e_mode):
<ul>
<li> TC (Two's complement)
<li> US (Unsigned)
</ul>
TC is \e default.
\warning Fix, Fixed, CFix and CFixed always use \e signed 64-bit integers to
represent the fixed-point data. Therefore it is not recommended to declare
variables with 64 bits and sign encoding mode US.
\subsection fix_base_omode Overflow mode
Supported overflow modes (itpp::o_mode):
<ul>
<li> SAT (Saturation)
<li> WRAP (Wrap-around)
</ul>
WRAP is \e default.
\note Fix, Fixed, CFix and CFixed apply this restriction during initialization
and assignments only.
\subsection fix_base_qmode Quantization mode
Supported quantization modes (itpp::q_mode), with definitions borrowed from
SystemC (see SystemC documentation for further details):
<ul>
<li> RND (Rounding to plus infinity): Add the most significant deleted bit to
the remaining bits.
<li> RND_ZERO (Rounding to zero): If the most significant deleted bit is 1,
and either the sign bit or at least one other deleted bit is 1, add 1 to
the remaining bits.
<li> RND_MIN_INF (Rounding to minus infinity): If the most significant deleted
bit is 1, and at least one other deleted bit is 1, add 1 to the remaining
bits.
<li> RND_INF (Rounding to infinity): If the most significant deleted bit is 1,
and either the inverted value of the sign bit or at least one other
deleted bit is 1, add 1 to the remaining bits.
<li> RND_CONV (Convergent rounding with half-way value rounded to even value):
If the most significant deleted bit is 1, and either the least
significant of the remaining bits or at least one other deleted bit is 1,
add 1 to the remaining bits.
<li> RND_CONV_ODD (Convergent rounding with half-way value rounded to odd
value): If the most significant deleted bit is 1, and either the least
significant of the remaining bits is 0 or at least one other deleted bit
is 1, add 1 to the remaining bits (not defined in SystemC).
<li> TRN (Truncation): Just copy the remaining bits.
<li> TRN_ZERO (Truncation to zero): If the sign bit is 1, and either the most
significant deleted bit or at least one other deleted bit is 1, add 1 to
the remaining bits.
</ul>
TRN is \e default. RND and TRN are usually the most implementation friendly.
However, note that it is RND_INF that corresponds to "ordinary rounding" and
TRN_ZERO that corresponds to "ordinary truncation".
\note Fix, Fixed, CFix and CFixed apply this restriction during initialization
and right-shift operations only.
\subsection fix_base_stat Statistics object pointer
Supported statistics object pointer values: either a pointer to an itpp::Stat
object or 0. 0 is \e default.
The sample method in the statistics object is called during initializations
and assignments. A single statistics object can collect statistics from more
than one fixed-point variable.
\subsection fix_base_outputmode Output mode
Supported output modes (itpp::output_mode), used by the output stream operator
\<\<:
<ul>
<li> OUTPUT_FIX: Output fixed-point representation only
<li> OUTPUT_FIX_SHIFT: Output fixed-point representation followed by \<shift\>
<li> OUTPUT_FLOAT: Output floating-point value
<li> OUTPUT_FLOAT_SHIFT: Output floating-point value followed by \<\<shift
</ul>
OUTPUT_FIX_SHIFT is \e default. Unlike the other modes, output_mode is a
\e static data member of Fix_Base, i.e. the output_mode is common for all
fixed-point variables. Use the following commands to change output_mode:
\code
Fix_Base::set_output_mode(OUTPUT_FIX);
Fix_Base::set_output_mode(OUTPUT_FIX_SHIFT);
Fix_Base::set_output_mode(OUTPUT_FLOAT);
Fix_Base::set_output_mode(OUTPUT_FLOAT_SHIFT);
// Alternative using a string parameter
Fix_Base::set_output_mode("OUTPUT_FIX");
Fix_Base::set_output_mode("OUTPUT_FIX_SHIFT");
Fix_Base::set_output_mode("OUTPUT_FLOAT");
Fix_Base::set_output_mode("OUTPUT_FLOAT_SHIFT");
// Alternative using an ostream modifier
cout << OUTPUT_FIX;
cout << OUTPUT_FIX_SHIFT;
cout << OUTPUT_FLOAT;
cout << OUTPUT_FLOAT_SHIFT;
\endcode
\section fix_real Fix and Fixed
Fix and Fixed are real-valued fixed-point data types primarily intended to
replace \c double when a design is refined from floating- to fixed-point
implementation. The data is stored in the least significant bits of a 64-bit
integer variable.
The following example shows how to declare a two's complement (i.e. a signed)
20-bit variable with wrap-around as overflow handling with the initial value
3.14 shifted up 10 bits:
\code
Fix a(3.14, 10, 20, TC, WRAP);
Fixed<20, TC, WRAP> b(3.14, 10);
\endcode
Note that Fix takes the initial values as well as the fixed-point restrictions
as constructor arguments. Fixed also takes the initial values as constructor
arguments but it takes the fixed-point restrictions as template arguments.
Choose Fix or Fixed depending on your needs. There are three main reasons why
you would want to choose Fix instead of Fixed. First, if you want to change
the fixed-point restrictions for a variable during run time, you have to use
Fix, since the fixed-point restrictions for Fixed have been "fixed" at compile
time. Second, if your code is using a lot of templating, you might end up with
many more template arguments if you use Fixed than you would if you use Fix,
since each set of fixed-point restrictions that you want to use will
correspond to another type (based on the class template Fixed) instead of just
different configurations of a single type (Fix). Third, the vector and matrix
operations currently work better for Fix than for Fixed.
\note Fixed is derived from Fix, which means that operators, methods and
functions for Fix can be used for Fixed as well. However, the functions for
Vec<Fix> (fixvec) and Mat<Fix> (fixmat) cannot be used for Vec<Fixed> and
Mat<Fixed>.
If you choose Fix, you should also read the section \ref fix_factory. If you
choose Fixed, you may find it convenient to use the following typedefs:
\code
typedef Fixed<1, TC, WRAP> fixed1; // for Fixed with 1 bit
...
typedef Fixed<64, TC, WRAP> fixed64; // for Fixed with 64 bits
typedef Fixed<1, US, WRAP> ufixed1; // for Unsigned Fixed with 1 bit
...
typedef Fixed<64, US, WRAP> ufixed64; // for Unsigned Fixed with 64 bits
typedef Fixed<1, TC, SAT> sfixed1; // for Saturated Fixed with 1 bit
...
typedef Fixed<64, TC, SAT> sfixed64; // for Saturated Fixed with 64 bits
typedef Fixed<1, US, SAT> sufixed1; // for Saturated Unsigned Fixed with 1 bit
...
typedef Fixed<64, US, SAT> sufixed64; // for Saturated Unsigned Fixed with 64 bits
\endcode
\note These typedefs use the default values for quantization mode (TRN) and
statistics object pointer value (0). Also note that U stands for Unsigned but
S stands for Saturated, NOT for Signed.
Declaration corresponding to the above Fixed example but using one of the
typedefs:
\code
fixed20 b(3.14, 10);
\endcode
\section fix_complex CFix and CFixed
CFix and CFixed are complex-valued fixed-point data types primarily intended
to replace <tt>complex<double></tt> when a design is refined from floating- to
fixed-point implementation. The data is stored in the least significant bits
of two 64-bit integer variables: one for the real part and one for the
imaginary part. The two parts have a common shift factor (the one inherited
from Fix_Base), so it is not possible to shift only one of them.
The following example shows two ways to declare a two's complement (i.e. a
signed) 20-bit variable with wrap-around as overflow handling with the initial
value 1.11 + 2.22i shifted up 10 bits:
\code
CFix a(1.11, 2.22, 10, 20, TC, WRAP);
CFixed<20, TC, WRAP> b(1.11, 2.22, 10);
CFix c(complex<double>(1.11, 2.22), 0.0, 10, 20, TC, WRAP);
CFixed<20, TC, WRAP> d(complex<double>(1.11, 2.22), 0.0, 10);
\endcode
\note The shift factor is passed as the third argument to the CFix/CFixed
constructors. If the first argument is complex, the second argument is a
dummy (that was set to 0.0 in the examples above).
Choose CFix or CFixed depending on your needs; see section \ref fix_real. If
you choose CFix, you should also read the section \ref fix_factory.
\note CFixed is derived from CFix, which means that operators, methods and
functions for CFix can be used for CFixed as well. However, the functions for
Vec<CFix> (cfixvec) and Mat<CFix> (cfixmat) cannot be used for Vec<CFixed> and
Mat<CFixed>.
If you choose CFixed, you may find it convenient to use the following
typedefs, which are predefined in IT++:
\code
typedef CFixed<1, TC, WRAP> cfixed1; // for CFixed with 1 bit
...
typedef CFixed<64, TC, WRAP> cfixed64; // for CFixed with 64 bits
typedef CFixed<1, TC, SAT> scfixed1; // for Saturated CFixed with 1 bit
...
typedef CFixed<64, TC, SAT> scfixed64; // for Saturated CFixed with 64 bits
\endcode
\note These typedefs use the default values for sign encoding mode (TC),
quantization mode (TRN) and statistics object pointer value (0). Also note
that S stands for Saturated, NOT for Signed.
Declarations corresponding to the above CFixed examples but using one of the
typedefs:
\code
cfixed20 b(1.11, 2.22, 10);
cfixed20 d(complex<double>(1.11, 2.22), 0.0, 10);
\endcode
\section fix_factory Fix_Factory
IF you choose to use Fix/CFix (instead of Fixed/CFixed) AND you want to
declare an Array/Vec/Mat with Fix/CFix elements AND you wish to specify
some non-default fixed-point restrictions for these elements (i.e. something
else than 64-bit word length, two's complement as sign encoding mode,
wrap-around as overflow mode, truncation as quantization mode, and no
statistics object), THEN you will need to use a Fix_Factory when declaring the
Array/Vec/Mat of Fix/CFix. Here is how it works, somewhat simplified: you give
the fixed-point restrictions as parameters to the Fix_Factory, then you give
the Fix_Factory as a parameter to the Array/Vec/Mat, and finally the
Array/Vec/Mat uses the Fix_Factory to create Fix/CFix elements with those
fixed-point restrictions. All constructors for Array, Vec and Mat can take a
Fix_Factory (or any other Factory for that matter) as their last, optional
argument. It is assumed that all elements in the Array/Vec/Mat should have the
same fixed-point restrictions (and use a common statistics object, if any).
Note that a Fix_Factory can create both Fix and CFix objects. For information
on Factory in general and Fix_Factory in particular, see the Detailed
Descriptions for itpp::Factory and itpp::Fix_Factory, respectively.
The following example shows how to declare a vector of length 7 with Fix
elements that are two's complement 20-bit variables with wrap-around as
overflow handling:
\code
Vec<Fix> a(7, FIX20);
\endcode
FIX20 is one of many predefined Fix_Factory; see the Detailed Description for
itpp::Fix_Factory.
\note One might wonder why the Array/Vec/Mat classes themselves cannot take
the fixed-point restrictions as parameters directly and create the Fix/CFix
elements without help from a Fix_Factory. The main benefit with the chosen
solution is that the Array/Vec/Mat classes are not "contaminated" with
knowledge (parameters, methods, etc) that is specific to the Fix/CFix types.
If the user for some reason prefers to use some other type (i.e. a type not
known by IT++) as the Array/Vec/Mat element type, this should work fine as
long as he or she creates a corresponding Factory. And this is exactly the
way that Fix/CFix and Fix_Factory work.
Fix/CFix should not need to know about Fix_Factory, but for the sake of
uniform syntax in declarations, an exception has been made:
\code
Fix a(FIX20);
\endcode
i.e. a Fix/CFix declaration can take a Fix_Factory as an argument, just like
the Vec<Fix> declaration above did.
\note All declarations with a Fix_Factory as a constructor argument also work
in templated code; see the Detailed Description for itpp::Fix_Factory.
\section fix_ops Operators and methods
\subsection fix_ops_asn Initialization and assignment
Fixed-point variables can be initialized with a fixed- or a floating-point
value:
\code
// Initialize a with the floating-point value double(3.14*pow2(10))
// and word length 20, two's complement, wrap-around and rounding
Fix a(3.14, 10, 20, TC, WRAP, RND);
// Initialize b with the fixed-point value a
// and word length 7, two's complement, wrap-around and rounding
Fix b(a, 7, TC, WRAP, RND);
\endcode
In this example, \c b was initialized with the same value as \c a but with
smaller word length resulting in overflow, since round(3.14*pow2(10)) does not
fit in the 7-bit variable \c b.
\warning All fixed-point data types have default constructors. For Fix/CFix,
the default constructor gives full word length (64 bits). If you call
templated functions with Fix/CFix as the template argument, they might use
these default constructors for declaration of temporary variables, which may
then contain unrestricted (64-bit) temporary results. If you want these
temporary results to be restricted, then you may have to modify the function
to introduce fixed-point restrictions for the temporary results, and even
introduce new temporary variables in order to avoid more than one operation
per expression (demonstrated in an example below). For Fixed/CFixed, on the
other hand, the default constructor gives certain fixed-point restrictions,
but note that it may still be necessary to introduce other fixed-point
restrictions as well as new temporary variables in the function.
The assignment operators =, +=, -=, *=, /=, <<= and >>= are supported. For =,
+=, -=, *= and /=, the right-hand operand can be another fixed-point variable
or an integer value. If it is an integer value, it is interpreted as a
fixed-point value with shift factor 0. The = operator simply copies the
shift factor from the right side to the left side. For information on how the
other operators treat the shift factor, see sections \ref fix_ops_add,
\ref fix_ops_mult and \ref fix_ops_shift.
If assignment to a scaled \c double is desired (when initialization has
already taken place), the itpp::Fix::set method can be used.
\code
// Initialize c with the floating-point value double(3.14*pow2(10))
// The shift factor is set to 10
Fix c(3.14, 10);
// Set c equal to 123. The shift factor is set to 0
// Note that the old shift factor 10 is discarded
c = 123;
// Set c equal to the integer portion of double(3.14*pow2(10))
// The shift factor is set to 10 (again)
c.set(3.14, 10);
// Achieve the same result using a temporary variable
// Note that the assignment operator copies the shift factor
c = Fix(3.14, 10);
\endcode
When the floating-point value is quantized, the quantization mode of the
fixed-point variable (TRN in the example above, since \c c has this
quantization mode) will be used, unless some other quantization mode (e.g.
RND) is specified as a third argument to set:
\code
c.set(3.14, 10, RND);
\endcode
\note If you write templated code, you are better off if you use the set_fix
function described in section \ref fix_fcn_setfix instead of the set method.
There are also methods for setting data representation and shift directly:
itpp::Fix::set_re, itpp::CFix::set_im and itpp::Fix_Base::set_shift. They are
mainly intended for internal use.
\subsection fix_ops_add Addition and subtraction
Addition and subtraction between two fixed-point variables as well as between
a fixed-point variable and an integer variable is supported. The unary minus
operator is also defined. For Fix and CFix, several vector and matrix
operations are also supported.
\code
// Declare a fixed-point vector with 7 elements
// (using the predefined Fix_Factory FIX20)
Vec<Fix> d(7, FIX20);
// Set all 7 elements equal to 77 with shift factor 0
d = Fix(77);
// Declare an integer vector with 7 elements
ivec e = "1 2 3 4 5 6 7";
// Add fixed-point vector d and integer vector e. Both have shift factor 0
Vec<Fix> f(d + e, FIX20);
\endcode
\note The addition and subtraction operators require that both operands have
the same shift factor, unless at least one of the operands is zero. If \c d
had been assigned with a different shift factor than 0 in the above example
(and ASSERT_LEVEL > 0), the addition <tt>d + e</tt> would have failed,
resulting in termination with the error message "assert_shifts: Different
shifts not allowed!".
As hinted earlier, the fixed-point restrictions are applied during
initialization, assignment and bit-shifting operations only. This means that
the result of an addition or subtraction is unrestricted (64 bits).
\code
Fix g(0, 0, 8, TC, SAT);
Fix h(100, 0, 8, TC, SAT);
Fix i(100, 0, 8, TC, SAT);
Fix j(-100, 0, 8, TC, SAT);
// The result of h + i is unrestricted (64 bits) but when it is assigned to g,
// it is restricted according to the fixed-point restrictions of g (8 bits).
// We get overflow, since 100+100=200 doesn't fit in an 8-bit signed variable.
// The saturated result will be 127
g = h + i;
// But now we don't get overflow since 100+100-100=100 does fit!
g = h + i + j;
// If we do want the temporary result to be restricted, we have to make
// an explicit temporary variable (with appropriate restrictions) for it
Fix tmp(0, 0, 8, TC, SAT);
// The first sum will be saturated to 127
tmp = h + i;
// The final sum will be 127-100=27, i.e. we got a different
// result when we introduced a restricted temporary variable
g = tmp + j;
\endcode
\subsection fix_ops_mult Multiplication and division
Multiplication and division between two fixed-point variables as well as
between a fixed-point variable and an integer variable is supported. For Fix
and CFix, several vector and matrix operations are also supported.
As stated earlier, the fixed-point restrictions are applied during
initialization, assignment and bit-shifting operations only. This means that
the result of a multiplication or division is unrestricted (64 bits) in the
same way as for an addition or subtraction; see section \ref fix_ops_add.
The resulting shift factor after a multiplication is the sum of the two shift
factors, while the resulting shift factor after a division is the difference
between the numerator shift factor and the denominator shift factor. The
result of a division is always quantized using truncation, i.e. the
quantization modes of the involved fixed-point variables do not matter. Note
that sometimes divisions can be replaced with multiplications and/or
bit-shifting operations; see section \ref fix_ops_shift.
\warning Complex multiplications and divisions are supported, but they utilize
temporary variables with full word length (64 bits).
\subsection fix_ops_shift Bit-shifting
The <<= and >>= operators are defined for the fixed-point data types. As an
alternative, you can use the itpp::Fix::lshift and itpp::Fix::rshift methods.
The appropriate fixed-point restrictions of the variable are applied, i.e.
for left-shifting the overflow mode is applied and for right-shifting the
quantization mode is applied. There is also a version of rshift that takes a
quantization mode as the last argument (but there is no corresponding version
of the >>= operator since it cannot take an extra argument).
\code
// Declare a fixed-point variable with the default quantization mode (TRN)
Fix a(3.14, 10);
// Right shift 5 bits using the quantization mode of a (i.e. TRN)
a.rshift(5);
// Right shift 5 bits using the specified quantization mode (i.e. RND)
a.rshift(5, RND);
\endcode
\note If you write templated code, you are better off if you use the
lshift_fix and rshift_fix functions described in section \ref fix_fcn_shiftfix
instead of the <<= and >>= operators and the lshift and rshift methods.
The << and >> operators are not defined for the fixed-point data types since
it is not clear what quantization mode that should be applied for the >>
operator.
\subsection fix_ops_conv Conversion
Fix and Fixed can be converted to double, while CFix and CFixed can be
converted to complex<double>. The conversion operators "un-shift" the data by
multiplying the fixed-point bit representation with pow2(-shift).
The itpp::Fix::unfix and itpp::CFix::unfix methods can always be used:
\code
Fix a(3.14, 5);
cout << a.unfix() << endl;
\endcode
The resulting output is 3.125.
\note If you write templated code, you are better off if you use the
functions unfix or to<T> described in sections \ref fix_fcn_unfix and
\ref fix_fcn_to instead of the unfix method.
Equivalently, the double(Fix&) and complex<double>(CFix&) operators can be
used, unless you define NO_IMPLICIT_FIX_CONVERSION before you include IT++
in your program.
\code
Fix a(3.14, 5);
cout << double(a) << endl;
\endcode
The resulting output is 3.125.
Finally, Fix/Fixed can be converted to CFix/CFixed using the appropriate
CFix/CFixed constructors.
\subsection fix_ops_get Get data members
This example shows how to get the data members of fixed-point variables:
\code
Fix a;
int64_t the_bit_representation = a.get_re();
int the_shift_factor = a.get_shift();
int the_word_length = a.get_wordlen();
e_mode the_sign_encoding_mode = a.get_e_mode();
o_mode the_overflow_mode = a.get_o_mode();
q_mode the_quantization_mode = a.get_q_mode();
int64_t max_bit_representation = a.get_max();
int64_t min_bit_representation = a.get_min();
\endcode
\note For CFix and CFixed, you get the bit representation for the imaginary
part with the method get_im().
\subsection fix_ops_io Input and output
The print() method outputs the entire state; see section \ref fix_ops_get.
\code
Fix a;
a.print();
\endcode
This code example shows how to input and output fixed-point numbers:
\code
CFix a(FIX8);
a.set(0.0, 0.0, 4);
cout << "Old a: " << a << endl;
cout << "New a? ";
cin >> a;
cout << "New a: " << a << endl;
\endcode
Complex numbers can be input on both the C++ form and the IT++ form:
\code
Old a: 0+0i<4>
New a? 1+2i
New a: 1+2i<4>
\endcode
\code
Old a: 0+0i<4>
New a? (1,2)
New a: 1+2i<4>
\endcode
\note The output_mode is OUTPUT_FIX_SHIFT in these examples; see section
\ref fix_base_outputmode.
In the above examples, only the data representation was changed, while the
shift (4) was kept. It is however possible to enter another (positive or
negative) shift factor as well:
\code
Old a: 0+0i<4>
New a? 1+2i<5>
New a: 1+2i<5>
\endcode
It is also possible to enter a floating-point value and a (positive or
negative) shift, rather than the data representation and a shift, if a
slightly different format is used:
\code
Old a: 0+0i<4>
New a? 1+2i<<5
New a: 32+64i<5>
\endcode
The resulting data representation is the entered floating-point value 1+2i
multiplied by 2^5.
\note In order to enter a negative shift, write 1+2i<<-5. It is not possible
to write 1+2i>>5.
Vectors and matrices support the same formats for fixed-point numbers.
However, all old elements are assumed to have the same shift factor, and the
shift factor of the first old element becomes the default shift factor for all
elements of the vector or matrix. The same holds in e.g. an Array of vectors,
i.e. the shift factor of the first old element in each vector becomes the
default shift factor for all elements of that vector. The default shift factor
in an empty vector or matrix is zero.
\section fix_fcn Functions
\subsection fix_fcn_isfix Function is_fix
The function itpp::is_fix returns true only if the argument is of type Fix or
CFix or an Array/Vec/Mat of Fix or CFix.
\code
Array<Array<Vec<Fix> > > aavf(FIX20);
bool will_be_true = is_fix(aavf);
\endcode
\warning Unfortunately, the function is_fix returns false if the argument is
of type Fixed or CFixed.
\subsection fix_fcn_setfix Function set_fix
The function itpp::set_fix sets <tt>y = x * pow2(n)</tt> if the first argument
is of type Fix or CFix or an Array/Vec/Mat of Fix or CFix. If the first
argument is of type double or complex<double> or an Array/Vec/Mat of double or
complex<double>, the function just sets <tt>y = x</tt>.
\code
Fix fix_var(FIX20);
set_fix(fix_var, 3.14, 10);
// fix_var will equal the integer portion of 3.14 * pow2(10)
double double_var(FIX20);
set_fix(double_var, 3.14, 10);
// double_var will just equal 3.14
\endcode
When the floating-point value is quantized, the quantization mode of the first
argument (TRN in the example above, since fix_var has this quantization mode)
will be used, unless some other quantization mode (e.g. RND) is specified as a
fourth argument to set_fix:
\code
set_fix(fix_var, 3.14, 10, RND);
\endcode
\subsection fix_fcn_shiftfix Functions lshift_fix and rshift_fix
The functions itpp::lshift_fix and itpp::rshift_fix perform left and right
bit-shifts, respectively, if the first argument is of type Fix or CFix or an
Array/Vec/Mat of Fix or CFix. If the first argument is of type double or
complex<double> or an Array/Vec/Mat of double or complex<double>, the
functions do not do anything at all.
\code
// This will right-shift fix_var 10 bits
rshift_fix(fix_var, 10);
// This will not affect double_var
rshift_fix(double_var, 10);
\endcode
When a fixed-point value is right-shifted using rshift_fix, the quantization
mode of the first argument (TRN in the example above, since fix_var has this
quantization mode) will be used, unless some other quantization mode (e.g.
RND) is specified as a third argument to rshift_fix:
\code
rshift_fix(fix_var, 10, RND);
\endcode
When a fixed-point value is left-shifted using lshift_fix, on the other hand,
the overflow mode of the first argument is always used.
\subsection fix_fcn_assert Function assert_fixshift
The itpp::assert_fixshift function can be used to verify that the shift factor
has the expected value:
\code
Fix a(3.14, 5);
// We will pass this check since 5 = 5
assert_fixshift(a, 5);
// The program will terminate (if ASSERT_LEVEL > 0) since 5 != 6
assert_fixshift(a, 6);
\endcode
If the first argument is of type double or complex<double> instead, no test
will be performed (since they have no shift factors).
\subsection fix_fcn_unfix Function unfix
The itpp::unfix function converts a fixed-point variable to a floating-point
variable (or an Array/Vec/Mat of fixed-point variables to an Array/Vec/Mat of
floating-point variables) by multiplying the fixed-point bit representation
with pow2(-shift), using the unfix method mentioned above.
\code
Fix a(3.14, 5);
double b = unfix(a);
Array<Mat<CFix> > c(FIX40);
cin >> c;
Array<cmat> d = unfix(c);
\endcode
If the argument is a floating-point variable (or an Array/Vec/Mat of
floating-point variables) instead, the function just returns the argument.
\subsection fix_fcn_to Function to<T>
The itpp::to<T> function is a very general conversion function. It converts a
floating- or fixed-point variable to a floating- or fixed-point variable (or
a floating- or fixed-point Array/Vec/Mat to a floating- or fixed-point
Array/Vec/Mat) depending on the types of the argument and of the specified
template parameter.
\code
// Convert a Vec<double> to a Vec<Fix> and assign it to f
Vec<double> e = "1.0 2.0 3.0";
Vec<Fix> f;
f = to<Fix>(e); // convert e "to Fix"
// Convert an Array<Array<Mat<Fix> > > called g to
// an Array<Array<Mat<CFix> > > and assign it to h
Array<Array<Mat<CFix> > > h;
h = to<CFix>(g); // convert g "to CFix"
\endcode
\note The variants to<double>(x) and to<complex<double> >(x) provide the same
functionality as unfix(x).
\warning Be aware that the variants to<Fix>(x) and to<CFix>(x) will return
a fixed-point variable with the shift factor(s) set to zero if x is a
floating-point variable. However, if x is a fixed-point variable, the shift
will be copied to the return variable.
\subsection fix_fcn_other Other functions
<ul>
<li> itpp::abs
<li> itpp::real
<li> itpp::imag
<li> itpp::conj
</ul>
*/
//!@{
//! Representation for fixed-point data types
typedef int64_t fixrep;
//! Max word length
const int MAX_WORDLEN = 64;
//! Table for fast multiplication or division by 2^n
const uint64_t UINT64_POW2[64] = {
uint64_t(1), uint64_t(1) << 1, uint64_t(1) << 2, uint64_t(1) << 3, uint64_t(1) << 4,
uint64_t(1) << 5, uint64_t(1) << 6, uint64_t(1) << 7, uint64_t(1) << 8, uint64_t(1) << 9,
uint64_t(1) << 10, uint64_t(1) << 11, uint64_t(1) << 12, uint64_t(1) << 13, uint64_t(1) << 14,
uint64_t(1) << 15, uint64_t(1) << 16, uint64_t(1) << 17, uint64_t(1) << 18, uint64_t(1) << 19,
uint64_t(1) << 20, uint64_t(1) << 21, uint64_t(1) << 22, uint64_t(1) << 23, uint64_t(1) << 24,
uint64_t(1) << 25, uint64_t(1) << 26, uint64_t(1) << 27, uint64_t(1) << 28, uint64_t(1) << 29,
uint64_t(1) << 30, uint64_t(1) << 31, uint64_t(1) << 32, uint64_t(1) << 33, uint64_t(1) << 34,
uint64_t(1) << 35, uint64_t(1) << 36, uint64_t(1) << 37, uint64_t(1) << 38, uint64_t(1) << 39,
uint64_t(1) << 40, uint64_t(1) << 41, uint64_t(1) << 42, uint64_t(1) << 43, uint64_t(1) << 44,
uint64_t(1) << 45, uint64_t(1) << 46, uint64_t(1) << 47, uint64_t(1) << 48, uint64_t(1) << 49,
uint64_t(1) << 50, uint64_t(1) << 51, uint64_t(1) << 52, uint64_t(1) << 53, uint64_t(1) << 54,
uint64_t(1) << 55, uint64_t(1) << 56, uint64_t(1) << 57, uint64_t(1) << 58, uint64_t(1) << 59,
uint64_t(1) << 60, uint64_t(1) << 61, uint64_t(1) << 62, uint64_t(1) << 63
};
//! Table for fast multiplication by 2^(n-64)
const double DOUBLE_POW2[128] = {
0.5 / UINT64_POW2[63], 1.0 / UINT64_POW2[63], 1.0 / UINT64_POW2[62], 1.0 / UINT64_POW2[61],
1.0 / UINT64_POW2[60], 1.0 / UINT64_POW2[59], 1.0 / UINT64_POW2[58], 1.0 / UINT64_POW2[57],
1.0 / UINT64_POW2[56], 1.0 / UINT64_POW2[55], 1.0 / UINT64_POW2[54], 1.0 / UINT64_POW2[53],
1.0 / UINT64_POW2[52], 1.0 / UINT64_POW2[51], 1.0 / UINT64_POW2[50], 1.0 / UINT64_POW2[49],
1.0 / UINT64_POW2[48], 1.0 / UINT64_POW2[47], 1.0 / UINT64_POW2[46], 1.0 / UINT64_POW2[45],
1.0 / UINT64_POW2[44], 1.0 / UINT64_POW2[43], 1.0 / UINT64_POW2[42], 1.0 / UINT64_POW2[41],
1.0 / UINT64_POW2[40], 1.0 / UINT64_POW2[39], 1.0 / UINT64_POW2[38], 1.0 / UINT64_POW2[37],
1.0 / UINT64_POW2[36], 1.0 / UINT64_POW2[35], 1.0 / UINT64_POW2[34], 1.0 / UINT64_POW2[33],
1.0 / UINT64_POW2[32], 1.0 / UINT64_POW2[31], 1.0 / UINT64_POW2[30], 1.0 / UINT64_POW2[29],
1.0 / UINT64_POW2[28], 1.0 / UINT64_POW2[27], 1.0 / UINT64_POW2[26], 1.0 / UINT64_POW2[25],
1.0 / UINT64_POW2[24], 1.0 / UINT64_POW2[23], 1.0 / UINT64_POW2[22], 1.0 / UINT64_POW2[21],
1.0 / UINT64_POW2[20], 1.0 / UINT64_POW2[19], 1.0 / UINT64_POW2[18], 1.0 / UINT64_POW2[17],
1.0 / UINT64_POW2[16], 1.0 / UINT64_POW2[15], 1.0 / UINT64_POW2[14], 1.0 / UINT64_POW2[13],
1.0 / UINT64_POW2[12], 1.0 / UINT64_POW2[11], 1.0 / UINT64_POW2[10], 1.0 / UINT64_POW2[9],
1.0 / UINT64_POW2[8], 1.0 / UINT64_POW2[7], 1.0 / UINT64_POW2[6], 1.0 / UINT64_POW2[5],
1.0 / UINT64_POW2[4], 1.0 / UINT64_POW2[3], 1.0 / UINT64_POW2[2], 1.0 / UINT64_POW2[1],
1.0, 1.0*UINT64_POW2[1], 1.0*UINT64_POW2[2], 1.0*UINT64_POW2[3],
1.0*UINT64_POW2[4], 1.0*UINT64_POW2[5], 1.0*UINT64_POW2[6], 1.0*UINT64_POW2[7],
1.0*UINT64_POW2[8], 1.0*UINT64_POW2[9], 1.0*UINT64_POW2[10], 1.0*UINT64_POW2[11],
1.0*UINT64_POW2[12], 1.0*UINT64_POW2[13], 1.0*UINT64_POW2[14], 1.0*UINT64_POW2[15],
1.0*UINT64_POW2[16], 1.0*UINT64_POW2[17], 1.0*UINT64_POW2[18], 1.0*UINT64_POW2[19],
1.0*UINT64_POW2[20], 1.0*UINT64_POW2[21], 1.0*UINT64_POW2[22], 1.0*UINT64_POW2[23],
1.0*UINT64_POW2[24], 1.0*UINT64_POW2[25], 1.0*UINT64_POW2[26], 1.0*UINT64_POW2[27],
1.0*UINT64_POW2[28], 1.0*UINT64_POW2[29], 1.0*UINT64_POW2[30], 1.0*UINT64_POW2[31],
1.0*UINT64_POW2[32], 1.0*UINT64_POW2[33], 1.0*UINT64_POW2[34], 1.0*UINT64_POW2[35],
1.0*UINT64_POW2[36], 1.0*UINT64_POW2[37], 1.0*UINT64_POW2[38], 1.0*UINT64_POW2[39],
1.0*UINT64_POW2[40], 1.0*UINT64_POW2[41], 1.0*UINT64_POW2[42], 1.0*UINT64_POW2[43],
1.0*UINT64_POW2[44], 1.0*UINT64_POW2[45], 1.0*UINT64_POW2[46], 1.0*UINT64_POW2[47],
1.0*UINT64_POW2[48], 1.0*UINT64_POW2[49], 1.0*UINT64_POW2[50], 1.0*UINT64_POW2[51],
1.0*UINT64_POW2[52], 1.0*UINT64_POW2[53], 1.0*UINT64_POW2[54], 1.0*UINT64_POW2[55],
1.0*UINT64_POW2[56], 1.0*UINT64_POW2[57], 1.0*UINT64_POW2[58], 1.0*UINT64_POW2[59],
1.0*UINT64_POW2[60], 1.0*UINT64_POW2[61], 1.0*UINT64_POW2[62], 1.0*UINT64_POW2[63]
};
//! Sign encoding modes (aligned with SystemC)
enum e_mode {
TC, //!< Two's complement
US //!< Unsigned
};
//! Overflow modes (aligned with SystemC)
enum o_mode {
SAT, //!< Saturation
SAT_ZERO, //!< Saturation to zero (Not implemented)
SAT_SYM, //!< Symmetrical saturation (Not implemented)
WRAP, //!< Wrap-around
WRAP_SM //!< Sign magnitued wrap-around (Not implemented)
};
//! Quantization modes (aligned with SystemC)
enum q_mode {
RND, //!< Rounding to plus infinity
RND_ZERO, //!< Rounding to zero
RND_MIN_INF, //!< Rounding to minus infinity
RND_INF, //!< Rounding to infinity
RND_CONV, //!< Convergent rounding with half-way value rounded to even value
RND_CONV_ODD, //!< Convergent rounding with half-way value rounded to odd value (not defined in SystemC)
TRN, //!< Truncation
TRN_ZERO //!< Truncation to zero
};
//! Output modes
enum output_mode {
OUTPUT_FIX, //!< Output fixed-point representation only
OUTPUT_FIX_SHIFT, //!< Output fixed-point representation followed by \<shift\> (default)
OUTPUT_FLOAT, //!< Output floating-point value
OUTPUT_FLOAT_SHIFT //!< Output floating-point value followed by \<\<shift
};
/*!
\brief Base class for fixed-point data types
See the Detailed Description in the \ref fixed module.
*/
class ITPP_EXPORT Fix_Base
{
public:
//! Default constructor
explicit Fix_Base(int s = 0, int w = MAX_WORDLEN, e_mode e = TC, o_mode o = WRAP, q_mode q = TRN, Stat *ptr = 0)
: shift(s), wordlen(w), emode(e), omode(o), qmode(q), stat_ptr(ptr) {init();}
//! Copy constructor
Fix_Base(const Fix_Base &x)
: shift(x.shift), wordlen(MAX_WORDLEN), emode(TC), omode(WRAP), qmode(TRN), stat_ptr(0) {init();}
//! Destructor
virtual ~Fix_Base() {}
//! Set shift (without shifting)
void set_shift(int s) {shift = s;}
//! Set output mode to OUTPUT_FIX, OUTPUT_FIX_SHIFT, OUTPUT_FLOAT or OUTPUT_FLOAT_SHIFT. Static member function.
static void set_output_mode(output_mode o) {outputmode = o;}
//! Set output mode to "OUTPUT_FIX", "OUTPUT_FIX_SHIFT", "OUTPUT_FLOAT" or "OUTPUT_FLOAT_SHIFT". Static member function.
static void set_output_mode(std::string o);
//! Get shift
int get_shift() const {return shift;}
//! Get word length
int get_wordlen() const {return wordlen;}
//! Get sign encoding mode
e_mode get_e_mode() const {return emode;}
//! Get overflow mode
o_mode get_o_mode() const {return omode;}
//! Get quantization mode
q_mode get_q_mode() const {return qmode;}
//! Get output mode
output_mode get_output_mode() const {return outputmode;}
//! Get maximum value of data representation
fixrep get_max() const {return max;}
//! Get minimum value of data representation
fixrep get_min() const {return min;}
//! Print restrictions
virtual void print() const;
protected:
//! Accumulated bitshift (positive means left-shifted, negative means right-shifted)
int shift;
//! Word length
int wordlen;
//! Sign encoding mode
e_mode emode;
//! Overflow mode
o_mode omode;
//! Quantization mode
q_mode qmode;
//! Pointer to statistics object
Stat *stat_ptr;
//! Minimum allowed value (help variable to speed up calculations)
fixrep min;
//! Maximum allowed value (help variable to speed up calculations)
fixrep max;
//! Number of unused (MSB) bits (help variable to speed up calculations)
int n_unused_bits;
//! Calculate help variables min, max and n_unused_bits
void init();
//! Handle overflows using overflow mode \c omode and make call to statistics object (if any)
fixrep apply_o_mode(fixrep x) const;
//! Convert from \c double to \c fixrep using \c shift and quantization mode \c qmode, then call <tt>limit()</tt>
fixrep scale_and_apply_modes(double x) const {return scale_and_apply_modes(x, qmode);}
//! Convert from \c double to \c fixrep using \c shift and quantization mode \c q, then call <tt>limit()</tt>
fixrep scale_and_apply_modes(double x, q_mode q) const;
//! Right shift \c n bits using quantization mode \c qmode and make call to statistics object (if any)
fixrep rshift_and_apply_q_mode(fixrep x, int n) const {return rshift_and_apply_q_mode(x, n, qmode);}
//! Right shift \c n bits using quantization mode \c q and make call to statistics object (if any)
fixrep rshift_and_apply_q_mode(fixrep x, int n, q_mode q) const;
private:
//! Output mode
static output_mode outputmode;
};
//! Set output mode
inline std::ostream &operator<<(std::ostream &os, const output_mode &o)
{
Fix_Base::set_output_mode(o);
return os;
}
//!@}
} // namespace itpp
#endif // #ifndef FIX_BASE_H
|