Boost logo

Boost :

Subject: Re: [boost] [review] Multiprecision review scheduled for June 8th - 17th, 2012
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-06-03 13:45:35


Le 03/06/12 18:37, Christopher Kormanyos a écrit :
> Thank you once again for your detailed report, Vicente.
>
>>>> I have spent some hours reading the documentation.
>>>> Here are some comments and a lot of questions.
>
>>> Did you get a chance to use it also? You always have such good comments,
>>> that we would benefit from some your experience with use-cases.
>> I would like to create a backend for my fixed_point library before the review.
> Wow! That was fast. It seems like just yesterday when
> we were preliminarily talking about your development.
Hrr, unfortunately I have not implemented closed arithmetic operations
on my fixed_point library, so I can not create the backend yet.
>> I have run the test and I'm getting a lot of errors for
>> test_float_io_cpp_dec_float
>> bjam toolset=clang-2.9,clang-2.9x -j2
>> Precision is: 13
>> Got: -987654312.0000000000000
>> Expected: -0.0000000008567
>> Testing value -8.5665356058806096939e-10
>> Formatting flags were: fixed showpos
>> Precision is: 13
>> Got: -987654312.0000000000000
>> Expected: -0.0000000008567
>> 9360 errors detected.
>> EXIT STATUS: 1
>> ====== END OUTPUT ======
> OK. This one looks like a real nugget of a find. You can never
> do enough testing. I just ran the tests on Visual Studio 2010 and
> they all pass. I don't have clang but if we can't track this down
> relatively easily, I can build it.
>
> The error report tells me a few things.
> * The number is completely wrong. So it's not just a rounding thing.
> * It might be related to the conversion to string.
> * On the other hand, it could be related to the actual algorithms.
>
> Before I download and build that compiler from source,
> could you please do two things for me?
>
> 1) Could you please zip and send the entire error text?
> Or if all 9360 errors are simply too big of a file, maybe
> the first 1000 error text messages or so. I would like to
> see if there is a visible trend in the kinds of numbers failing.
>
> 2) Could you please (with your compiler) create the
> reported number from string as
> cpp_dec_float_50(" -8.5665356058806096939e-10")?
> Then simply print it out with precision(13), fixed and showpos.
> This helps me see if the error is merely in printout or
> rather goes deeper into the class algorithms.
>
> I used the code below and got a sensible result of -0.0000000008567.
>
> #include<iomanip>
> #include<iostream>
>
> #include<boost/multiprecision/cpp_dec_float.hpp>
>
> int main(int, char**)
> {
> boost::multiprecision::cpp_dec_float_50 x("-8.5665356058806096939e-10");
>
> std::cout<< std::setprecision(13)
> << std::fixed
> << std::showpos
> << x
> << std::endl;
> }
The result is

-0.0000000008567

>> and others like
>> darwin.compile.c++ bin/floating_point_examples.test/darwin-4.2.1/debug/floating_point_examples.o
>> ../example/floating_point_examples.cpp:11:17: error: array: No such file or directory
>> ../example/floating_point_examples.cpp: In function 'mp_type mysin(const mp_type&)':
>> ../example/floating_point_examples.cpp:361: error: expected initializer before '<' token
>> ../example/floating_point_examples.cpp:666: error: expected `}' at end of input
>> "g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -g -dynamic -gdwarf-2
>> -fexceptions -fPIC -I"../../.." -I"/Users/viboes/boost/trunk"
>> -c -o "bin/floating_point_examples.test/darwin-4.2.1/debug>
>> /floating_point_examples.o" "../example/floating_point_examples.cpp"
> These are easy to understand. It's probably *my bad* on this one
> because I used some of C++11 in selected samples. For example,
> in the polynomial expansion of my_sin(), I use std::array.
> In the functional derivative and integral examples, I use a
> C++11 anonymous (lambda) function.
>
> Please tell me if I need to avoid using C++11 in the examples
> due to boost policy. I would like to use these examples because
> they exhibit where I want to go with the language. But if
> boost policy demands, I can re-write for C++03.
There is no issue using specific c++11, but the example should be run
either only on c++11 mode or just compile conditionally the c++11 parts.
>
>>> Accordingly, we do support this:
>>>
>>> boost::multiprecision::cpp_dec_float_100 a(boost::multiprecision::cpp_dec_float_100(123) / 100);
>>> boost::multiprecision::cpp_dec_float_50 b(boost::multiprecision::cpp_dec_float_50(456) / 100);
>>> boost::multiprecision::cpp_dec_float_50 c = boost::multiprecision::cpp_dec_float_50(a) * b;
>>>
>>> But we do not support this:
>>>
>>> boost::multiprecision::cpp_dec_float_100 a(boost::multiprecision::cpp_dec_float_100(123) / 100);
>>> boost::multiprecision::cpp_dec_float_50 b(boost::multiprecision::cpp_dec_float_50(456) / 100);
>>> boost::multiprecision::cpp_dec_float_50 c = a * b;
>> This is OK as there is no implicit conversion from cpp_dec_float_100
>> to cpp_dec_float_50. But I would expect
>> boost::multiprecision::cpp_dec_float_100 d = a * b;
>> to compile, but it doesn't. Why the implicit conversion from
>> cpp_dec_float_50 to cpp_dec_float_100 doesn't helps?
> Well, I guess this is simply a design choice. At this time,
> we decided to prohibit both narrowing as well as
> widening implicit conversion of binary arithmetic
> operations. This means that you need to explicitly
> convert both larger as well as smaller digit ranges
> in binary arithmetic operations. For example,
>
> boost::multiprecision::cpp_dec_float_100 d = a * boost::multiprecision::cpp_dec_float_100(b);

This not answer my question "Why the implicit conversion from
cpp_dec_float_50 to cpp_dec_float_100 doesn't helps?". Have you an idea?
>
>>> To be quite honest, I do not have the time to work out a sensible
>>> rounding scheme for the base-10 back-end in a reasonable time
>>> schedule. One of the difficulties of base-10 is its unruly nature
>>> regarding rounding.
>> I understand your words as, the user can not configure the way
>> rounding is done. But AFAIU it is valid to do a conversion,
>> so the documentation should add which kind of rounding is applied.
> <snip>
>
>> so I guess the rounding is towards zero.
> Yes. you are right. My previous post was also misleading.
> The cpp_dec_float back-end does not round on operations
> or conversions from 50 to 100 digits, etc. It does, however,
> round when preparing an output string. I believe that
> I used round-to-zero. John has indicated a slight preference
> not to document these internal details.

Yes but it round while converting 100 digits to 50, and this should be
documented.
>
>>>>> * Do you plan to add constexpr and noexcept to the interface?
>>>>> After thinking a little bit I'm wondering if this is this possible
>>>>> when using 3pp libraries backends that don't provide them?
>>>> I'm also not sure if it's possible, or even what we would gain - I can't
>>>> offhand think of any interfaces that could use constexp for example.
>>> If you are aiming at compile-time constant mp_numbers, then
>>> I do not believe it is possible with the specified low-complexity
>>> constraints a constexpr functions and objects.
>>>
>>> This works with state-of-the-art compilers today.
>>> constexpr double pi = 3.14159265358979323846
>>>
>>> But this may not work soon, or ever.
>>> constexpr boost::multiprecision::cpp_dec_float_50 pi("3.14159265358979323846264338327950288419716939937510582097494");
>> Not all operations can be defined as constexpr but I will expect some to be.
>> constexpr boost::multiprecision::cpp_dec_float_50 pi(3.14159265358979323846);
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html
>> propose also to have some kind of literals through some factory methods.
>> |to_nonnegative<2884,-4>()| will produce a |nonnegative| constant with
>> a range and resolution just sufficient to hold the value 2884*2^-4.
>> I don't know if this kind of factories could be applicable to the current backends.
> I suspect it can not be applied to the current back-ends
> because the creation of a big number from a string or
> a built-in type simply exceeds the low-complexity
> limit required for constexpr. Maybe I'm wrong here.
> Your idea is certainly a valid goal to look for in the future.
Does this mean that we can not create a generic class mp_number that
provides some of the interfaces the backend can provide and the user
will need to be able to create instances of mp_number from instances of
the backend.

Could the following constructor be implemented as a constexpr if the
move of BE is a constexpr?

constexpr mp_number<BE>::mp_number(const BE&&);

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk