- Lapacke inputs - 4 Updates
- A baffling bug in my bignumber code (expressive C++ dialect) - 6 Updates
- copy-on-write - 1 Update
- enable thread support in libevent - 2 Updates
- Overloading global function in a class - 2 Updates
- Returning class object: is it inefficient? - 2 Updates
- using override keyword in cpp file - 3 Updates
- A baffling bug in my bignumber code (expressive C++ dialect) - 5 Updates
scott@slp53.sl.home (Scott Lurndal): Feb 24 01:41PM >putted, so that means it shouldn't be an input but rather an output. So why= > it exists inside LAPACKE_ssyev( ... , &w); I don't understand. >Sorry, I'm very new to programming. I appreciate your time. It seems evident that the W parameter is an output parameter. Since the function will be storing a value indirectly through the pointer, you don't need to initialize the variable before passing its address to the function. |
thebtc@hotmail.com: Feb 24 09:49AM -0800 Thank you Ben and Scott for your help. It seems that my problems are not over however because now I'm having trouble printing my eigenvalues to a text file. Here is my code: #include <iostream> #include <fstream> #include <string> #include "lapacke.h" using namespace std; int main(){ char jobz = 'N'; // computes eigenvalues only char uplo = 'U'; // stores the upper triangle of a in an array a int n = 10; // the order of the matrix a float a[n][n]= { {1, 11, 7, 9, 7, 11, 7, 9, 2, 11}, {11, 4, 10, 10, 6, 2, 9, 6, 10, 0}, {7, 10, 3, 5, 4, 4, 4, 4, 6, 10,}, {9, 10, 5, 3, 8, 8, 3, 5, 1, 8,}, {7, 6, 4, 8, 8, 10, 5, 6, 10, 0}, {11, 2, 4, 8, 10, 9, 4, 3, 5, 11}, {7, 9, 4, 3, 5, 4, 3, 10, 7, 2}, {9, 6, 4, 5, 6, 3, 10, 11, 1, 7}, {2, 10, 6, 1, 10, 5, 7, 1, 10, 5}, {11, 0, 10, 8, 0, 11, 2, 7, 5, 1} }; // the symmetric matrix a for which the eigenvalues will be found int lda = n; // the leading dimension of the array a float w[n]; // stores the eigenvalues }; // end of declarations ofstream fout("eigenvaluesA.txt"); fout << "eigenvalues of matrix A" << endl; LAPACKE_ssyev(&jobz, &uplo, &n, a, &lda, &w); fout.close(); I keep getting the following errors: 'fout' does not name a type. How can it not name a type if I specified the namespace std thing at the beginning? I also get the error expected constructor, destructor, or type conversion before '(' token LAPACKE_ssyev(&jobz, &uplo, &n, a, &lda, &w); However I am following several articles right now with examples that all list Lapacke and its inputs as I did above. so I'm not sure what is wrong with that line either. Any input is much appreciated. |
scott@slp53.sl.home (Scott Lurndal): Feb 24 06:19PM >expected constructor, destructor, or type conversion before '(' token > LAPACKE_ssyev(&jobz, &uplo, &n, a, &lda, &w); >However I am following several articles right now with examples that all list Lapacke and its inputs as I did above. so I'm not sure what is wrong with that line either. Any input is much appreciated. put your code _inside_ main, not outside of it. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 24 08:09PM thebtc@hotmail.com writes: I'll make a few more remarks... > {2, 10, 6, 1, 10, 5, 7, 1, 10, 5}, > {11, 0, 10, 8, 0, 11, 2, 7, 5, 1} > }; // the symmetric matrix a for which the eigenvalues will be found C++ does not permit this sort of array. The size of a plain array must be a compile-time constant and, despite is being obvious to you, n is not a compile-time constant. Writing float a[10][10] would be fine, as would float a[][] = { { ... }, { ... }, ... { ... } }; where the compiler will deduce that the size is 10x10. > fout << "eigenvalues of matrix A" << endl; > LAPACKE_ssyev(&jobz, &uplo, &n, a, &lda, &w); > fout.close(); This needs to go into main. But then you will find other problems. Firstly, you are not passing enough arguments to LAPACKE_ssyev and the ones you are passing are of the wrong type. In general, you won't need any of those &s. In fact, you don't need many of those variables -- you can pass 'N' and 'U' directly rather than by putting them into jobz and uplo. <snip> -- Ben. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 12:41AM +0100 > $var instead of auto? Why don't you like the auto keyword? I don't /dislike/ `auto`. But `auto` has many different meanings, and that makes it • hard to search for e.g. variable declarations as opposed to constant or reference declarations, • hard to see at a glance what kind of declaration (such as variable or constant, as in the array example below) a declaration is, • hard to see what type a declaration is about, and • I believe, difficult to learn to use correctly for a novice. These are problems that are somewhat alleviated by the $ pseudo-keywords. There are also problems, some mentioned below, that are irrelevant for the use or not of pseudo-keywords, at least as long as they're macros and not more real keywords supported by compiler extension. I think it's easier now to do compiler extensions, with clang's support machinery. But the last time I tried my hand at that, with gcc (for an idea about exception handling), I found that gcc had a really complex structure expressed in the apparently lowest possible level K&R C... • • • Regarding the claim of hard to see type, consider auto s = "Blah"; Until I learned this as a special case (that didn't take long, but until) I thought this would deduce `s` as `char const[5]`, which is non-assignable and with length. But it deduces `s` as `char const*`. Which is not even a constant, so one can, perhaps inadvertently, do s = "Oh!"; Well, then perhaps change the declaration to auto s[] = "Blah"; // ? But contrary to what I think is a natural expectation, one just can't use `auto` for an array item type: that won't compile. The /technically/ correct way when one desires `s` as an immutable array with length information retained, as the initializer, is to write auto& s = "Blah"; But I wouldn't do that because it just obscures the desired result. With the pseudo-keywords one can, however, write quite naturally $let s = "Blah"; // `s` is const, decayed to pointer $var s = "Blah"; // `s` is variable, decayed to pointer $name s = "Blah"; // `s` is `char const[5]` where • $let → auto const, always yielding just a constant /value/; • $var → auto, always yielding a mutable /variable/; and • $name → auto&, always yielding just an /alias/. Still lacking is a way to express decay_t<decltype( *"Blah" )> s[] = "Blah"; which yields a mutable array, `char[5]`. A macro for this would get /too/ ugly not just because it would have to take the initializer as argument, but because that initializer could easily contain a comma or two, which would be interpreted as macro argument separators. Well, a variadic macro would be able to handle that, but it would still be ugly. • • • As an example of a problem that as far as I can see is not generally solvable with keywords, consider the following code: template< class Some_type > using ref_ = Some_type&; template< class Stream > auto int_from( ref_<Stream> stream ) -> int { int result; stream >> result; if( stream.fail() ) { abort(); } return result; } auto input_int( ref_<const wstring> prompt ) -> int { wcout << prompt; return int_from( wcin ); // <--- Deducing the type Stream. } That works fine. But the second declaration here does not work fine: void foo() { auto& yep = wcin; ref_<auto> nope = wcin; // <--- Uh oh. (void) yep; (void) nope; } The problem here isn't the reference, which is just one specific use case, it's the use of `auto` as a template (alias) argument. The good old general template argument type deduction can see right through that little template alias, as in the `ref_<Stream>`, but `auto` just doesn't cut it. > Why do you prefer obfuscation to idiomatic C++? What you are doing > try to make C++ code look like code from other inferior languages is > really egregious. Well, those are emotional reactions. I don't share them. :) Actually I felt happy being able to express how I think about things (just also slightly annoyed at having to use evil macros etc.). For re the inferior languages, I think that to use C++ in a good way one must have a clear picture of what /hypothetical language constructs/, usually very much like constructs from other languages that one has used, one is trying to implement with one's C++ code. For example, to me, header and implementation files, and the whole thing with include guards etc., implements modules, like Modula-2 MODULE or Pascal UNIT or Ada PACKAGE. I haven't really used Ada but I've read some books about it. And for example, to me, my `i_up_to` for a range-based loop, implements in an imperfect but practically useful way, Python 2.7 `xrange` or Python 3.x `range`. And correspondingly, e.g. the $let pseudo keyword in the expressive dialect implements in a very restricted and awkward, but IMHO still very practically useful, way, a logical `let` from a functional language or maths. Cheers!, - Alf |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 23 07:18PM -0600 > pseudo keyword in the expressive dialect implements in a very restricted > and awkward, but IMHO still very practically useful, way, a logical > `let` from a functional language or maths. Apart from yourself who are you trying to convince? Really bad. /Flibble |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 03:16AM +0100 On 24.02.2017 02:18, Mr Flibble wrote: > Apart from yourself who are you trying to convince? Really bad. I replied because you asked. Now you quoted everything just to point out that you can't remember asking, and you wonder who. That's dumb. Cheers!, - Alf |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 05:26AM +0100 On 24.02.2017 01:33, Stefan Ram wrote: > R = ::std::move( x ); > x = ::std::move( r ); > r = ::std::move( a ); }} Oh. :) I confirmed, by writing my own little program for that, that you get a correct result. Although it is for index 999.999 in the sequence, when one considers fib(0) = 1, fib(1) = 1, fib(2) = 2, fib(3) = 3 and so on. I'm not sure how your code works, it seems to do strange things, but here's the expressive C++ dialect code that I cooked up to test it and show how I would have written that program: [code] #include <p/expressive/using_weakly_all.hpp> #include <algorithm> #include <iostream> #include <math.h> // log #include <vector> using namespace std; using Big_int = std::vector<int>; // Each item is a decimal digit. $procedure add_to( ref_<Big_int> a, ref_<const Big_int> b ) { $let size_a = n_items_in( a ); $let size_b = n_items_in( b ); $var carry = 0; for( $each i $in i_up_to( max( size_a, size_b ) ) ) { if( i >= size_a ) { a.resize( i + 1 ); } a[i] += carry + ($when( i < size_b ) $use( b[i] ) $default_to( 0 )); carry = a[i]/10; a[i] -= 10*carry; } if( carry != 0 ) { a.push_back( carry ); } } $just { $let golden_ratio = 1.6180339887498948482045868343656; $let n = 100'000; $let n_digits = static_cast<int>( (n + 10)*log10( golden_ratio ) + 1 ); clog << n_digits << " digits expected.\n"; $var a = Big_int{1}; a.reserve( n_digits ); $var b = Big_int{0}; b.reserve( n_digits ); for( $n_times( n ) ) { $var next = a; add_to( next, b ); a = move( b ); b = move( next ); } for( $each digit $in reverse_span_of( b ) ) { cout << digit; } cout << endl; } [/code] I did not take the trouble to split the addition loop into parts where the processing could be specialized for speed; I just used `-O3`. ;-) This might be the reason that this code is shorter, 43 versus 91 lines, even though my code looks much more verbose and whitespacey-ish. Cheers!, - Alf PS: One problem with the $n_times macro is that g++ produces a very much undesired warning "-Wno-unused-but-set-variable". I just turn it off but I would like to suppress it for this situation in the code. I tried with `_Pragma` expressions in the macro but g++ would have none of that inside a `for` loop head. The macro is currently defined as `$e::Dummy_reference_consumer $unique_temp_name $in $e::i_up_to( n )`. I can't think of a way to do that without a range based loop. |
Robert Wessel <robertwessel2@yahoo.com>: Feb 24 01:19AM -0600 On 24 Feb 2017 02:58:43 GMT, ram@zedat.fu-berlin.de (Stefan Ram) wrote: > 1.4 seconds. And this was only in Firefox, Chrome might > even be faster. Amazing what they can get out of > interpreters today! The better Javascript processors are JITs these days. |
Tim Rentsch <txr@alumni.caltech.edu>: Feb 24 12:08PM -0800 > Which is possibly in the subtraction operator or something, but I'm > exhausted & hungry; I'll eat and watch a movie, and see tomorrow if > anyone saw something blindingly obviously wrong? I think some other replies have let you find the bug. I just wanted to add my vote for using regular C++ rather than the "expressive" flavor when posting this kind of stuff. To look at any code more than about 10 or 20 lines I would like to be able to compile it. If the code is written in "expressive" C++ I can't do that. |
Paul <pepstein5@gmail.com>: Feb 24 11:52AM -0800 Please could someone link to (or provide) an example of copy-on-write in C++. I know what it means, but I'd like to see a simple example. I didn't really find one that looked convincing on a Google search. I was asked about it in a job interview and got stumped. Because I did well enough on the other questions, I have now been invited back for a second interview, and I think they may test how much I've learned in the meantime. Many thanks, Paul |
kushal bhattacharya <bhattacharya.kushal4@gmail.com>: Feb 24 12:31AM -0800 Can anybody help in enabling thread support so that libevent automatically allocates lock for bufferevent from multiple threads |
red floyd <dont.bother@its.invalid>: Feb 24 11:18AM -0800 On 2/24/2017 12:31 AM, kushal bhattacharya wrote: > Can anybody help in enabling thread support so that libevent automatically allocates lock for bufferevent from multiple threads The C++ Standard says nothing about libevent. Try a Unix or or Linux group. |
Steve Keller <keller@no.invalid>: Feb 24 06:52PM +0100 For a simple interpreter I wrote a class class Stmt { public: virtual void exec() const = 0; ... }; and several statement classes derived from that. In these classes I have a number of occurrences of code like the following: class FooStmt : public Stmt { Stmt *s; public: virtual void exec() const { if (s) s->exec(); } }; Therefore, I added a wrapper void exec(const Stmt *s) { if (s) s->exec(); } However, in order to be able to call exec(const Stmt *) from inside FooStmt, I either need to a) make this wrapper a static member function of class Stmt b) if the wrapper is outside of class Stmt, I have to call it using ::exec(s) instead of only exec(s). c) rename the wrapper to something different than exec. It seems the compiler, when looking for an exec(const Stmt *) function, first looks for any exec(...) function in FooStmt and if it finds one (in this case the exec() member function without parameters) it does not continue to look for a matching exec(const Stmt *) outside of FooStmt. But why does is behave that way? I don't like any of these solutions because a) makes the wrapper visible in the header file and b) and c) look cumbersome. Are there other suggestions? Steve |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 24 08:53PM +0200 On 24.02.2017 19:52, Steve Keller wrote: > have a number of occurrences of code like the following: > class FooStmt : public Stmt { > Stmt *s; I assume you have taken care to consider why you can and need to use a raw pointer here instead of some standard smart pointer. > finds one (in this case the exec() member function without parameters) > it does not continue to look for a matching exec(const Stmt *) outside > of FooStmt. But why does is behave that way? It's a general rule in C++ to use the matching identifier from the closest scope (class scope in this case). Otherwise you could not write things like #include <complex.h> int foo(int arg) { return arg + 1; // ambiguity! is this the local parameter // or the arg() function from <complex.h>? } > I don't like any of these solutions because a) makes the wrapper > visible in the header file and b) and c) look cumbersome. Basically you want to have a special kind of pointer where dereferencing null is ignored. In C++ one writes a new class for such things: class ExecPtr { const Stmt* s; // ... public: void exec() const { if (s) { s->exec(); } } }; class FooStmt : public Stmt { ExecPtr s; public: virtual void exec() const { s.exec(); } }; |
Christiano <christiano@engineer.com>: Feb 24 02:22PM -0300 On 02/23/2017 01:35 AM, Christiano wrote: > // access d using d.day(), d.month(), and d.year() > // make new Date to return > } I was testing some codes here. See this C code: /----------- a1.c -----------------\ #include <stdio.h> struct house { int a; int b; }; struct house func() { struct house e = {2,3}; return e; } int main() { int num =8; struct house x = func(); printf("%d %d\n", x.a, x.b); return 0; } \---------------------------------/ Now, see the second version: /------------- a2.c -----------------------\ #include <stdio.h> struct house { int a; int b; }; struct house func() { return (struct house){2,3}; } int main() { int num =8; struct house x = func(); printf("%d %d\n", x.a, x.b); return 0; } \--------------------------------------/ The "func" function in the first version locally creates a "struct house" and then copies it to the "struct house" in the main. The "func" function in the second version creates the "struct house" in the main directly. It is possible to observe this in the generated assembly code using -S option (gcc/g++). In C++ things are not different. For example: Date new_date_random() { Date x = Date{ random_day(), random_month(), random_year() }; return x; } VERSUS Date new_date_random() { return Date{ random_day(), random_month(), random_year() }; } The first version locally creates a "Date" and then copies it to the "Date" outside. (Assuming here that there was no RVO optimization.) The second version creates the "Date" outside directly. That is, this information indicates that: In situations where we are not receiving references from the object outside, It is preferable whenever possible to return an unnamed literal class object. |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 24 08:24PM +0200 On 24.02.2017 19:22, Christiano wrote: > I was testing some codes here. Are you sure you compiled with optimization flags like -O2 ? This whole thread is all about optimizations, for testing them you need to switch them on. |
helpseeker <vijaybhaskar@gmail.com>: Feb 24 12:29AM -0800 Hi, I would like to know what is the general guidance/preference for using the override keyword in cpp files. I personally think that it is helpful to have the override keyword in the cpp files too so that it is easy to identify which methods are overridden and which are not. But I know its not needed to have the override keyword in cpp files. Is there a bad side to it though - to have override keyword in cpp file? Thanks |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 11:09AM +0100 On 24.02.2017 09:29, helpseeker wrote: > not. But I know its not needed to have the override keyword in cpp > files. Is there a bad side to it though - to have override keyword in > cpp file? Your decision to use `override` should not be influenced by the kind of file – whether header or implementation file like cpp. The kind of file plays a rôle for the compiler's assumption of what programming language the code is written in, and it plays a rôle for your assumption about how the file will be used, e.g. that a header file will be included and an implementation file used as the main code file for a translation unit. The by convention different usage means that one adopts some different conventions in header files versus implementation files, e.g. for include guards, use of `inline`, definitions of namespace scope variables. But this does not extend to use of `override` or not. There is no way that the different usage of different file types is related to what `override` is about. `override` is a safeguard against believing one overrides a base class' member function that isn't there or isn't virtual, and it's a safeguard against maintenance changing the signature of an overridden function, e.g. by adding a defaulted argument. So, it's effectively a part of the static type checking, even though it doesn't influence the type. Essentially it says to the compiler, "this is what I intend, namely an override, please check that for me", and clearly that has nothing to do with file types whatsoever. The cost is mainly that the syntax is awkward, with `override` at the end of the function head. That can present a formatting problem. But it's IMO a very small problem, and the safety is well worth it. Cheers & hth., - Alf |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 24 01:32PM +0200 On 24.02.2017 10:29, helpseeker wrote: > Hi, > I would like to know what is the general guidance/preference for using the override keyword in cpp files. I personally think that it is helpful to have the override keyword in the cpp files too so that it is easy to identify which methods are overridden and which are not. But I know its not needed to have the override keyword in cpp files. Is there a bad side to it though - to have override keyword in cpp file? What do you mean by 'in cpp file'? If you mean if you should repeat the override keyword in a member function definition outside of the class definition, then this is expressly forbidden by the current standard (C++14): 8.4.1/1: "A virt-specifier-seq can be part of a function-definition only if it is a member-declaration." 9.2/8: "A virt-specifier-seq shall appear only in the declaration of a virtual member function." |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 12:33AM >I decided to do a little challenge we used to give to the students in >Bodø in the mid 1990s: to implement a bignumber class and use it to >compute the Fibonacci sequence up to a ridiculous length. I did not really try to find the bug in your code, but I wrote a C++ program to print the 100'000th Fibonacci number. Disclaimer: it's a quick hack: One cannot really change the »< long, 1'000'000'000L >« below to something else, unless on also edits the »"000000000"« in »to_string«. Disclaimer: Code was slightly edited between the last test and the post, hope not to introduce new bugs. #include <algorithm> #include <cassert> #include <climits> #include <cmath> #include <cstdlib> #include <initializer_list> #include <iostream> #include <ostream> #include <string> using namespace ::std::literals; /* a vector that will grow on demand */ template< typename T > class vector : public ::std::vector< T > { public: using ::std::vector< T >::vector; /* delete the following function definition when your estimates for the number of digits in main are surely large enough (to trade some security for speed) */ T& operator[]( typename vector::size_type const i ) { while( i >= this->size() )this->push_back( 0 ); return( *( static_cast< ::std::vector< T >* >( this )))[ i ]; }}; /* a big number */ /* base must be less than MAX_DIGIT/2, say less than MAX_DIGIT/2-2, base must be a power of 10 for the simplistic to_string function below to be correct. */ template< typename DIGIT, DIGIT base > class bignum : public vector< DIGIT > { public: public: using vector< DIGIT >::vector; using digit_type = DIGIT; typename ::bignum<DIGIT,base>::size_type length; /* add h to g giving R, h must not be shorter than g, R is the result */ static void sum ( ::bignum<DIGIT,base> & g, ::bignum<DIGIT,base> & h, ::bignum<DIGIT,base> & R ) { typename ::bignum<DIGIT,base>::size_type p = 0; bool o = false; /* actually the carry bit */ while( p < g.length ) { DIGIT const s = o + g[ p ]+ h[ p ]; R[ p++ ]= s -( o = s > base )* base; } while( p < h.length ) { DIGIT const s = o + h[ p ]; R[ p++ ]= s -( o = s > base )* base ; } if( o ) { DIGIT const s = o; R[ p++ ]= s -( o = s > base )*base; } R.length = p; } static ::std::string to_string( ::bignum<DIGIT,base> & n ) { ::std::string result; result.reserve( 1000 ); for( int i = n.length; i > 0; ) { --i; if( i == n.length - 1 )result += ::std::to_string( n[ i ]); else { ::std::string s = ::std::to_string( n[ i ]); char const * p = "000000000" + s.length(); result += p; result += s; }} return result; } /* set the argument to the number one */ static void one( ::bignum<DIGIT,base> & x ) { x[ 0 ]= 1; x.length = 1; }}; int main() { using number = bignum< long, 1'000'000'000L >; number x( 30'000 ); number::one( x ); number r( 30'000 ); number::one( r ); number R( 30'000 ); number::one( R ); number a; for( long i = 2; i <= 100'000; ++i ) { bool print = i == 100'000; /* edit here to specify which values */ /* you want to be printed. */ if( print ) { ::std::string result = number::to_string( r ); ::std::cout << i << ' ' << result << '\n'; ::std::cout.flush(); } if( r.length < x.length )number::sum( r, x, R ); else number::sum( x, r, R ); a = ::std::move( R ); R = ::std::move( x ); x = ::std::move( r ); r = ::std::move( a ); }} |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 12:52AM >Java/C# have quite same roots but Java/Javascript? Nonsense connection. Using aggressive wording like »Nonsense« will not help to cover your lack of expertise. »The diktat from upper engineering management was that the language must "look like Java"«. - Brendan Eich |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 01:09AM >>Java/C# have quite same roots but Java/Javascript? Nonsense connection. >Using aggressive wording like »Nonsense« will not help >to cover your lack of expertise. Now I made the error that I dislike so much when I read it! An article (determiner) is missing in front of »aggressive wording«, but actually I intended to write the plural »aggressive wordings«, and the »s« somehow disappeared. |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 02:58AM >I did not really try to find the bug in your code, but I >wrote a C++ program to print the 100'000th Fibonacci number. I wrote a similar program in JavaScript: Turns out: Here the JavaScript program is not much slower than the compiled C++ program. The C++ program takes about 1 second here and the JavaScript program about 1.4 seconds. And this was only in Firefox, Chrome might even be faster. Amazing what they can get out of interpreters today! { const alpha = new Date().getTime(); const fib = ( () => { "use strict"; const e = 14; const b = eval( "1e" + e ); const f = Array( e ).join( "0" ); let x = new Float64Array( 3e4 ); x[ 0 ] = 1.0; let xl = 1; let r = new Float64Array( 3e4 ); r[ 0 ] = 1.0; let rl = 1; let R = new Float64Array( 3e4 ); let Rl = 0; let j = new Array( 3e4 ); let s = 0; let a; let al; let o = 0; let p = 0; let g; let G; let h; let H; const fibonacci =( n )=> { for( let i = 1; i < n - 1; ++i ) { if( rl < xl ){ g = r; G = rl; h = x; H = xl; } else { g = x; G = xl; h = r; H = rl; } p = 0; o = 0; while(p<G){s=o+g[p]+h[p];R[p++]=(s-(o=+(s>b))*b);} while(p<H){s=o+h[p];R[p++]=(s-(o=+(s>b))*b);} if(o!=0){s=o;R[p++]=(s-(o=+(s>b))*b);} Rl = p; a = R; al = Rl; R = x; Rl = xl; x = r; xl = rl; r = a; rl = al; } let i = 0; for( ; i < al - 1; ++i )j[ i ]=( f +( a[ i ] )).slice( -e ); j[ i ]= a[ i ]; return j.slice( 0, al ); } return fibonacci( 100000 ).reverse().join( "" ); } )() const omega = new Date().getTime(); console.log( fib ); console.log( omega - alpha ); } |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 03:08AM >Turns out: Here the JavaScript program is not much >slower than the compiled C++ program. The C++ program When I use »double« for a bignum digit, I can store 14 decimal digits in one bignum digit with C++, and then the program is about 10 % faster. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment