|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
On April 25 2016 19:31 Acrofales wrote: Could be that you forgot to call "make clean". I know that has cost me headaches worth of debugging...
But yes, I think every programmer worth his salt has spent hours being frustrated at a problem, deep into the night. And the next morning it turns out that the problem was completely trivial to solve, and you do it in 2 lines of code and 3 minutes. Feeling both victorious and relieved, as well as incredibly frustrated at the same time.
Actually sounds like the best bet, can’t remember though if I did clean build it before it started to work again or not. For the time being I calm myself down by telling me this was the problem.
On April 25 2016 18:29 Khalum wrote: You should really reconsider your way of using #includes. The way it looks every header includes every header. That's not how it should be done at all. Even if you use #pragma once.
Don't worry, that is not the case at all
|
hey all
chasing some urgent help with Python. The task is to re-create the RC4 encryption algorithm.
def encrypt(data,key): keystream=key_conversion(key) out=[]
for char in data: out.append("%02X" % (ord(char) ^ keystream.__next__())) hex_data=''.join(out)
return hex_data
def decrypt(data,key): keystream=key_conversion(key) out=[]
for char in data: out.append("%02X" % ord((char)) ^ keystream.__next__())
hex_data=''.join(out)
return hex_data
I'm testing using the RC4 Test Vectors en.wikipedia.org
encrypt('Plaintext', 'Key') 'BBF316E8D940AF0AD3'
works as expected
decrypt('BBF316E8D940AF0AD3', 'Key')
should return 'Plaintext' but it does not.
I am having a hell lot of trouble with decryption and I cannot figure out why - this is the error I get;
TypeError: unsupported operand type(s) for ^: 'str' and 'int' - I know this error is to do with the ord(char) line as I am trying to perform modulo on a string and an int, but I am unsure what conversions I need to do
Any ideas?
|
On April 26 2016 15:46 Sedzz wrote:hey all chasing some urgent help with Python. The task is to re-create the RC4 encryption algorithm. + Show Spoiler + def encrypt(data,key): keystream=key_conversion(key) out=[]
for char in data: out.append("%02X" % (ord(char) ^ keystream.__next__())) hex_data=''.join(out)
return hex_data
def decrypt(data,key): keystream=key_conversion(key) out=[]
for char in data: out.append("%02X" % ord((char)) ^ keystream.__next__())
hex_data=''.join(out)
return hex_data
I'm testing using the RC4 Test Vectors en.wikipedia.org encrypt('Plaintext', 'Key') 'BBF316E8D940AF0AD3'
works as expected decrypt('BBF316E8D940AF0AD3', 'Key')
should return 'Plaintext' but it does not. I am having a hell lot of trouble with decryption and I cannot figure out why - this is the error I get; TypeError: unsupported operand type(s) for ^: 'str' and 'int' - I know this error is to do with the ord(char) line as I am trying to perform modulo on a string and an int, but I am unsure what conversions I need to do Any ideas?
I'm not too familiar with python nor the algorithm in question, but it looks like you are trying to output hex values (%02X) in the decryption, which doesn't make sense.
I think what you want is to convert each incoming two hex characters to the respective int value, xor that with the keystream, convert it to an ascii character and then append it to the output.
Something like output.append(chr(convertMyHexByteToInt(char1, char2) ^ keystream.__next__()));
|
On April 26 2016 15:46 Sedzz wrote:hey all chasing some urgent help with Python. The task is to re-create the RC4 encryption algorithm. def encrypt(data,key): keystream=key_conversion(key) out=[]
for char in data: out.append("%02X" % (ord(char) ^ keystream.__next__())) hex_data=''.join(out)
return hex_data
def decrypt(data,key): keystream=key_conversion(key) out=[]
for char in data: out.append("%02X" % ord((char)) ^ keystream.__next__())
hex_data=''.join(out)
return hex_data
I'm testing using the RC4 Test Vectors en.wikipedia.org encrypt('Plaintext', 'Key') 'BBF316E8D940AF0AD3'
works as expected decrypt('BBF316E8D940AF0AD3', 'Key')
should return 'Plaintext' but it does not. I am having a hell lot of trouble with decryption and I cannot figure out why - this is the error I get; TypeError: unsupported operand type(s) for ^: 'str' and 'int' - I know this error is to do with the ord(char) line as I am trying to perform modulo on a string and an int, but I am unsure what conversions I need to do Any ideas?
It seems like you've just copy pasted this code from somewhere since you are not performing any modulo - that is python old style string formatting.
If you have decrypt and encrypt being the same function - which I guess makes sense since it's just XOR the data and the key - then why are they seperate function? It just opens you up to typos.
Compare
... out.append("%02X" % (ord(char) ^ keystream.__next__())) ...
to
... out.append("%02X" % ord((char)) ^ keystream.__next__()) ...
The first one is '02X' % (char xor encryption key). (so you are performing str(int xor int) The second one is ('02X' % char) xor encryption key (so you are performing str(int) xor int)
As to what the string formatting is - if you break it down - from reading https://docs.python.org/2/library/string.html '02' => output should be at least 2 characters else left pad it with 0 'X' => takes one integer argument, convert it to it's hex value (Hex format. Outputs the number in base 16, using upper- case letters for the digits above 9.) e.g. '%02X' % 0 == 00 '%02X' % 255 == FF
So again I'd argue - 1. If you have assignments in Python, learn Python or your life will suck because you have no idea wtf is going on and can't even google for help since you don't even know enough to google it 2. If you have 2 functions doing essentially the same thing, why are they 2 functions? Unless you plan on adding more to each function. 3. Normal python 3 style is that by implementing __next__() in a class you can call next(instance) rather than instance.__next__(). __next__() should raise StopIteration once it is out of data.
You can also just rewrite it as something like below
keystream=key_conversion(key) xored = ['02X' % (ord(c) ^ next(keystream)) for c in data] return ''.join(xored)
Or using zip
keystream = key_conversion(key) xored = ['02X' % (ord(d) ^ k) for d, k in zip(data, keystream)] return ''.join(xored)
I avoided using char since that then shadows python char. It's kinda funky since you're iterating over 2 iterators at the same time, so you have to take care that next(keystream) has enough data to work but I assume that's part of rc4 to make that happen - also your code makes same assumption.
|
On April 26 2016 18:13 teamamerica wrote:+ Show Spoiler +It seems like you've just copy pasted this code from somewhere since you are not performing any modulo - that is python old style string formatting. If you have decrypt and encrypt being the same function - which I guess makes sense since it's just XOR the data and the key - then why are they seperate function? It just opens you up to typos. Compare ... out.append("%02X" % (ord(char) ^ keystream.__next__())) ...
to ... out.append("%02X" % ord((char)) ^ keystream.__next__()) ...
The first one is '02X' % (char xor encryption key). (so you are performing str(int xor int) The second one is ('02X' % char) xor encryption key (so you are performing str(int) xor int) As to what the string formatting is - if you break it down - from reading https://docs.python.org/2/library/string.html'02' => output should be at least 2 characters else left pad it with 0 'X' => takes one integer argument, convert it to it's hex value (Hex format. Outputs the number in base 16, using upper- case letters for the digits above 9.) e.g. '02X' % 0 == 00 '02X' % 255 == FF So again I'd argue - 1. If you have assignments in Python, learn Python or your life will suck because you have no idea wtf is going on and can't even google for help since you don't even know enough to google it 2. If you have 2 functions doing essentially the same thing, why are they 2 functions? Unless you plan on adding more to each function. 3. Does calling __next__() seem wrong to you? Normal python 3 style is that by implementing __next__() in a class you can call next(instance) rather than instance.__next__(). __next__() should raise StopIteration once it is out of data - that exception doesn't need to be cause if you are keystream=key_conversion(key) out = "".join(['02X' % (ord(c) ^ next(keystream)) for c in data]
I avoided using char since that then shadows python char. It's kinda funky since you're iterating over 2 iterators at the same time, so you have to take care that next(keystream) has enough data to work but I assume that's part of rc4 to make that happen - also your code makes same assumption.
I'll admit i hastily copy pasted code into the message without double checking it, I have about four different versions of this and am testing each one.
Have finally settled on this
+ Show Spoiler + def encrypt(plaintext, key): key = key_conversion(key) Keystream = RC4(key) for X in plaintext: sys.stdout.write("%X" % (ord(X) ^ Keystream.__next__())) print
def decrypt(encrypted_text, key):
key = key_conversion(key) Keystream = RC4(key)
for X in encrypted_text: sys.stdout.write("%X" % (ord(X) ^ Keystream.__next__())) print
The reason I have two different functions is because I want the output of encrypt to be in hex where as I want the output of decrypt to be in plaintext (but for now have it outputting in hex so I can verify it's working)
So now I will work on getting the decrypt function output to plaintext
Cheers for your help! You definitely clarified some things up for me
|
OK, some very weird thing happened recently. Some dude just used the code I asked a question (and answered the same thing myself) on stackoverflow about java mail but didn't change the recipient so I got his test mails LOL. I'm feeling so proud of it. I even sent him a mail asking him if he needs more help about that thing. Didn't get a reply though.
Other than that, I just got a job for a geo business intelligence project and I'd like to do some homework about it. They will use spring boot with any of the three following databases in the backend: PostgreSQL, MongoDB or Couchbase, and leafletjs for map stuff. PostgreSQL is the only one I don't know shit about and my mongodb skills could definitely put some polishing to good use. Suggest me a simple project that I can build so that I can develop some handcraft.
|
Heh, was looking at dtoa.c today.
I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable...
The formatting is dreadful. There's plenty of single-letter variables, ifdef hell, gotos and stuff like:
++*s++
I've seen some shit in my life, but those have to be one of the worst 4.3k+ lines of code to be used worldwide...
This stuff performs wonders but looking at it is depressing.
|
On April 27 2016 00:07 Manit0u wrote:Heh, was looking at dtoa.c today. I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable... The formatting is dreadful. There's plenty of single-letter variables, ifdef hell, gotos and stuff like: ++*s++
I've seen some shit in my life, but those have to be one of the worst 4.3k+ lines of code to be used worldwide... This stuff performs wonders but looking at it is depressing.
It's a form of job protection
|
On April 27 2016 00:35 emperorchampion wrote:Show nested quote +On April 27 2016 00:07 Manit0u wrote:Heh, was looking at dtoa.c today. I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable... The formatting is dreadful. There's plenty of single-letter variables, ifdef hell, gotos and stuff like: ++*s++
I've seen some shit in my life, but those have to be one of the worst 4.3k+ lines of code to be used worldwide... This stuff performs wonders but looking at it is depressing. It's a form of job protection 
But this file is under the MIT license
|
On April 27 2016 00:07 Manit0u wrote:I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable... haha I think this every time I read basically anyone else's C/C++... and then I go 'well, shit, I actually wouldn't touch that with a ten-foot pole' because I know as well as everyone else that it *works*, dammit, and I don't want to be the one to break 30-year-old code
|
On April 27 2016 00:45 Manit0u wrote:Show nested quote +On April 27 2016 00:35 emperorchampion wrote:On April 27 2016 00:07 Manit0u wrote:Heh, was looking at dtoa.c today. I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable... The formatting is dreadful. There's plenty of single-letter variables, ifdef hell, gotos and stuff like: ++*s++
I've seen some shit in my life, but those have to be one of the worst 4.3k+ lines of code to be used worldwide... This stuff performs wonders but looking at it is depressing. It's a form of job protection  But this file is under the MIT license 
This reminds me of my engineering textbooks with 50 pages of FORTRAN code shoved in the back of the book...
|
On April 27 2016 00:07 Manit0u wrote:Heh, was looking at dtoa.c today. I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable... The formatting is dreadful. There's plenty of single-letter variables, ifdef hell, gotos and stuff like: ++*s++
I've seen some shit in my life, but those have to be one of the worst 4.3k+ lines of code to be used worldwide... This stuff performs wonders but looking at it is depressing. A compiler should just explode instead of compiling such bullshit. I hate it when people try to be "clever" like that.
|
It perhaps improved something for a certain compiler on a certain machine a long time ago, then was kept like this for decades.
|
On April 27 2016 01:55 spinesheath wrote:Show nested quote +On April 27 2016 00:07 Manit0u wrote:Heh, was looking at dtoa.c today. I really don't get it how after nearly 30 years of it being out and numerous people contributing to it no one has taken the route of making it more readable... The formatting is dreadful. There's plenty of single-letter variables, ifdef hell, gotos and stuff like: ++*s++
I've seen some shit in my life, but those have to be one of the worst 4.3k+ lines of code to be used worldwide... This stuff performs wonders but looking at it is depressing. A compiler should just explode instead of compiling such bullshit. I hate it when people try to be "clever" like that.
It's not "clever". It's fucking awful. I really hate people who'd rather do something like that instead of simply writing
*s += 2;
which is not only more readable and more efficient but is actually just one character longer. You can't be that lazy...
|
On April 27 2016 03:55 Manit0u wrote:It's not "clever". It's fucking awful. I really hate people who'd rather do something like that instead of simply writing *s += 2;
Uhhh... I don't think those are equivalent? I haven't checked but a = ++*s++; is actually equivalent to ++s; a = *s; ++s; if I'm not mistaken.
That being said, I think this proves your point - any time seven characters cause that much confusion things are going rapidly downhill
|
On April 27 2016 04:08 Cyx. wrote:Show nested quote +On April 27 2016 03:55 Manit0u wrote:It's not "clever". It's fucking awful. I really hate people who'd rather do something like that instead of simply writing *s += 2;
Uhhh... I don't think those are equivalent? I haven't checked but a = ++*s++; is actually equivalent to ++s; a = *s; ++s; if I'm not mistaken. That being said, I think this proves your point - any time seven characters cause that much confusion things are going rapidly downhill 
Where the hell did you come with the
a = ++*s++
It is
++*s++
You are not storing the value of *s anywhere after the operation. You are talking about something completely different here.
|
Which is why I put the "clever" in quotes. It is awful. Regardless of what the semantics actually are.
|
About those semantics... I tried to answer that by just looking at C documentation.
The postfix ++ has higher precedence than *, so the *s++ is *(s++). That one is moving the pointer. Because it's postfix, it does this after everything else on the line is processed.
The prefix ++ has the same precedence as *. Prefix operators apply from right to left, so ++*s is ++(*s). That one is adding something to the target value and is not changing the pointer.
I think the whole thing is then this (not sure):
++*s++;
++*(s++);
++*s; s++;
++(*s); s++;
*s += 1; s += 1;
|
Lemme put this in perspective:
char * dtoa #ifdef KR_headers (dd, mode, ndigits, decpt, sign, rve) double dd; int mode, ndigits, *decpt, *sign; char **rve; #else (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, then *decpt is set to 9999.
mode: 0 ==> shortest string that yields d when read in and rounded to nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives a return value similar to that of ecvt, except that trailing zeros are suppressed. 3 ==> through ndigits past the decimal point. This gives a return value similar to that from fcvt, except that trailing zeros are suppressed, and ndigits can be negative. 4,5 ==> similar to 2 and 3, respectively, but (in round-nearest mode) with the tests of mode 0 to possibly return a shorter string that rounds to d. With IEEE arithmetic and compilation with -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same as modes 2 and 3 when FLT_ROUNDS != 1. 6-9 ==> Debugging modes similar to mode - 4: don't try fast floating-point estimate (if applicable).
Values of mode other than 0-9 are treated as mode 0.
Sufficient space is allocated to the return value to hold the suppressed trailing zeros. */
int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case, try_quick; Long L; #ifndef Sudden_Underflow int denorm; ULong x; #endif Bigint *b, *b1, *delta, *mlo, *mhi, *S; U d2, eps, u; double ds; char *s, *s0; #ifndef No_leftright #ifdef IEEE_Arith U eps1; #endif #endif #ifdef SET_INEXACT int inexact, oldinexact; #endif #ifdef Honor_FLT_ROUNDS /*{*/ int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ Rounding = Flt_Rounds; #else /*}{*/ Rounding = 1; switch(fegetround()) { case FE_TOWARDZERO: Rounding = 0; break; case FE_UPWARD: Rounding = 2; break; case FE_DOWNWARD: Rounding = 3; } #endif /*}}*/ #endif /*}*/
#ifndef MULTIPLE_THREADS if (dtoa_result) { freedtoa(dtoa_result); dtoa_result = 0; } #endif
u.d = dd; if (word0(&u) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign = 1; word0(&u) &= ~Sign_bit; /* clear sign bit */ } else *sign = 0;
#if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith if ((word0(&u) & Exp_mask) == Exp_mask) #else if (word0(&u) == 0x8000) #endif { /* Infinity or NaN */ *decpt = 9999; #ifdef IEEE_Arith if (!word1(&u) && !(word0(&u) & 0xfffff)) return nrv_alloc("Infinity", rve, 8); #endif return nrv_alloc("NaN", rve, 3); } #endif #ifdef IBM dval(&u) += 0; /* normalize */ #endif if (!dval(&u)) { *decpt = 1; return nrv_alloc("0", rve, 1); }
#ifdef SET_INEXACT try_quick = oldinexact = get_inexact(); inexact = 1; #endif #ifdef Honor_FLT_ROUNDS if (Rounding >= 2) { if (*sign) Rounding = Rounding == 2 ? 0 : 2; else if (Rounding != 2) Rounding = 0; } #endif
b = d2b(&u, &be, &bbits); #ifdef Sudden_Underflow i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { #endif dval(&d2) = dval(&u); word0(&d2) &= Frac_mask1; word0(&d2) |= Exp_11; #ifdef IBM if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) dval(&d2) /= 1 << j; #endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) * * This suggests computing an approximation k to log10(d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); * * We want k to be too large rather than too small. * The error in the first-order Taylor series approximation * is in our favor, so we just round up the constant enough * to compensate for any error in the multiplication of * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, * adding 1e-13 to the constant term more than suffices. * Hence we adjust the constant term to 0.1760912590558. * (We could get a more accurate k by invoking log10, * but this is probably not worthwhile.) */
i -= Bias; #ifdef IBM i <<= 2; i += j; #endif #ifndef Sudden_Underflow denorm = 0; } else { /* d is denormalized */
i = bbits + be + (Bias + (P-1) - 1); x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) : word1(&u) << (32 - i); dval(&d2) = x; word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ i -= (Bias + (P-1) - 1) + 1; denorm = 1; } #endif ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0. && ds != k) k--; /* want k = floor(ds) */ k_check = 1; if (k >= 0 && k <= Ten_pmax) { if (dval(&u) < tens[k]) k--; k_check = 0; } j = bbits - i - 1; if (j >= 0) { b2 = 0; s2 = j; } else { b2 = -j; s2 = 0; } if (k >= 0) { b5 = 0; s5 = k; s2 += k; } else { b2 -= k; b5 = -k; s5 = 0; } if (mode < 0 || mode > 9) mode = 0;
#ifndef SET_INEXACT #ifdef Check_FLT_ROUNDS try_quick = Rounding == 1; #else try_quick = 1; #endif #endif /*SET_INEXACT*/
if (mode > 5) { mode -= 4; try_quick = 0; } leftright = 1; ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ /* silence erroneous "gcc -Wall" warning. */ switch(mode) { case 0: case 1: i = 18; ndigits = 0; break; case 2: leftright = 0; /* no break */ case 4: if (ndigits <= 0) ndigits = 1; ilim = ilim1 = i = ndigits; break; case 3: leftright = 0; /* no break */ case 5: i = ndigits + k + 1; ilim = i; ilim1 = i - 1; if (i <= 0) i = 1; } s = s0 = rv_alloc(i);
#ifdef Honor_FLT_ROUNDS if (mode > 1 && Rounding != 1) leftright = 0; #endif
if (ilim >= 0 && ilim <= Quick_max && try_quick) {
/* Try to get by with floating-point arithmetic. */
i = 0; dval(&d2) = dval(&u); k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ if (k > 0) { ds = tens[k&0xf]; j = k >> 4; if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; dval(&u) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) if (j & 1) { ieps++; ds *= bigtens[i]; } dval(&u) /= ds; } else if ((j1 = -k)) { dval(&u) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; dval(&u) *= bigtens[i]; } } if (k_check && dval(&u) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; dval(&u) *= 10.; ieps++; } dval(&eps) = ieps*dval(&u) + 7.; word0(&eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; dval(&u) -= 5.; if (dval(&u) > dval(&eps)) goto one_digit; if (dval(&u) < -dval(&eps)) goto no_digits; goto fast_failed; } #ifndef No_leftright if (leftright) { /* Use Steele & White method of only * generating digits needed. */ dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); #ifdef IEEE_Arith if (k0 < 0 && j1 >= 307) { eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */ word0(&eps1) -= Exp_msk1 * (Bias+P-1); dval(&eps1) *= tens[j1 & 0xf]; for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++) if (j & 1) dval(&eps1) *= bigtens[i]; if (eps.d < eps1.d) eps.d = eps1.d; } #endif for(i = 0;;) { L = dval(&u); dval(&u) -= L; *s++ = '0' + (int)L; if (1. - dval(&u) < dval(&eps)) goto bump_up; if (dval(&u) < dval(&eps)) goto ret1; if (++i >= ilim) break; dval(&eps) *= 10.; dval(&u) *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ dval(&eps) *= tens[ilim-1]; for(i = 1;; i++, dval(&u) *= 10.) { L = (Long)(dval(&u)); if (!(dval(&u) -= L)) ilim = i; *s++ = '0' + (int)L; if (i == ilim) { if (dval(&u) > 0.5 + dval(&eps)) goto bump_up; else if (dval(&u) < 0.5 - dval(&eps)) { while(*--s == '0'); s++; goto ret1; } break; } } #ifndef No_leftright } #endif fast_failed: s = s0; dval(&u) = dval(&d2); k = k0; ilim = ilim0; }
/* Do we have a "small" integer? */
if (be >= 0 && k <= Int_max) { /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; if (ilim < 0 || dval(&u) <= 5*ds) goto no_digits; goto one_digit; } for(i = 1;; i++, dval(&u) *= 10.) { L = (Long)(dval(&u) / ds); dval(&u) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ if (dval(&u) < 0) { L--; dval(&u) += ds; } #endif *s++ = '0' + (int)L; if (!dval(&u)) { #ifdef SET_INEXACT inexact = 0; #endif break; } if (i == ilim) { #ifdef Honor_FLT_ROUNDS if (mode > 1) switch(Rounding) { case 0: goto ret1; case 2: goto bump_up; } #endif dval(&u) += dval(&u); #ifdef ROUND_BIASED if (dval(&u) >= ds) #else if (dval(&u) > ds || (dval(&u) == ds && L & 1)) #endif { bump_up: while(*--s == '9') if (s == s0) { k++; *s = '0'; break; } ++*s++; } break; } } goto ret1; }
m2 = b2; m5 = b5; mhi = mlo = 0; if (leftright) { i = #ifndef Sudden_Underflow denorm ? be + (Bias + (P-1) - 1 + 1) : #endif #ifdef IBM 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); #else 1 + P - bbits; #endif b2 += i; s2 += i; mhi = i2b(1); } if (m2 > 0 && s2 > 0) { i = m2 < s2 ? m2 : s2; b2 -= i; m2 -= i; s2 -= i; } if (b5 > 0) { if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); b1 = mult(mhi, b); Bfree(b); b = b1; } if ((j = b5 - m5)) b = pow5mult(b, j); } else b = pow5mult(b, b5); } S = i2b(1); if (s5 > 0) S = pow5mult(S, s5);
/* Check for special case that d is a normalized power of 2. */
spec_case = 0; if ((mode < 2 || leftright) #ifdef Honor_FLT_ROUNDS && Rounding == 1 #endif ) { if (!word1(&u) && !(word0(&u) & Bndry_mask) #ifndef Sudden_Underflow && word0(&u) & (Exp_mask & ~Exp_msk1) #endif ) { /* The special case */ b2 += Log2P; s2 += Log2P; spec_case = 1; } }
/* Arrange for convenient computation of quotients: * shift left if necessary so divisor has 4 leading 0 bits. * * Perhaps we should just compute leading 28 bits of S once * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ i = dshift(S, s2); b2 += i; m2 += i; s2 += i; if (b2 > 0) b = lshift(b, b2); if (s2 > 0) S = lshift(S, s2); if (k_check) { if (cmp(b,S) < 0) { k--; b = multadd(b, 10, 0); /* we botched the k estimate */ if (leftright) mhi = multadd(mhi, 10, 0); ilim = ilim1; } } if (ilim <= 0 && (mode == 3 || mode == 5)) { if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { /* no digits, fcvt style */ no_digits: k = -1 - ndigits; goto ret; } one_digit: *s++ = '1'; k++; goto ret; } if (leftright) { if (m2 > 0) mhi = lshift(mhi, m2);
/* Compute mlo -- check for special case * that d is a normalized power of 2. */
mlo = mhi; if (spec_case) { mhi = Balloc(mhi->k); Bcopy(mhi, mlo); mhi = lshift(mhi, Log2P); }
for(i = 1;;i++) { dig = quorem(b,S) + '0'; /* Do we yet have the shortest decimal string * that will round to d? */ j = cmp(b, mlo); delta = diff(S, mhi); j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); #ifndef ROUND_BIASED if (j1 == 0 && mode != 1 && !(word1(&u) & 1) #ifdef Honor_FLT_ROUNDS && Rounding >= 1 #endif ) { if (dig == '9') goto round_9_up; if (j > 0) dig++; #ifdef SET_INEXACT else if (!b->x[0] && b->wds <= 1) inexact = 0; #endif *s++ = dig; goto ret; } #endif if (j < 0 || (j == 0 && mode != 1 #ifndef ROUND_BIASED && !(word1(&u) & 1) #endif )) { if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT inexact = 0; #endif goto accept_dig; } #ifdef Honor_FLT_ROUNDS if (mode > 1) switch(Rounding) { case 0: goto accept_dig; case 2: goto keep_dig; } #endif /*Honor_FLT_ROUNDS*/ if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); #ifdef ROUND_BIASED if (j1 >= 0 /*)*/ #else if ((j1 > 0 || (j1 == 0 && dig & 1)) #endif && dig++ == '9') goto round_9_up; } accept_dig: *s++ = dig; goto ret; } if (j1 > 0) { #ifdef Honor_FLT_ROUNDS if (!Rounding) goto accept_dig; #endif if (dig == '9') { /* possible if i == 1 */ round_9_up: *s++ = '9'; goto roundoff; } *s++ = dig + 1; goto ret; } #ifdef Honor_FLT_ROUNDS keep_dig: #endif *s++ = dig; if (i == ilim) break; b = multadd(b, 10, 0); if (mlo == mhi) mlo = mhi = multadd(mhi, 10, 0); else { mlo = multadd(mlo, 10, 0); mhi = multadd(mhi, 10, 0); } } } else for(i = 1;; i++) { *s++ = dig = quorem(b,S) + '0'; if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT inexact = 0; #endif goto ret; } if (i >= ilim) break; b = multadd(b, 10, 0); }
/* Round off last digit */
#ifdef Honor_FLT_ROUNDS switch(Rounding) { case 0: goto trimzeros; case 2: goto roundoff; } #endif b = lshift(b, 1); j = cmp(b, S); #ifdef ROUND_BIASED if (j >= 0) #else if (j > 0 || (j == 0 && dig & 1)) #endif { roundoff: while(*--s == '9') if (s == s0) { k++; *s++ = '1'; goto ret; } ++*s++; } else { #ifdef Honor_FLT_ROUNDS trimzeros: #endif while(*--s == '0'); s++; } ret: Bfree(S); if (mhi) { if (mlo && mlo != mhi) Bfree(mlo); Bfree(mhi); } ret1: #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { word0(&u) = Exp_1 + (70 << Exp_shift); word1(&u) = 0; dval(&u) += 1.; } } else if (!oldinexact) clear_inexact(); #endif Bfree(b); *s = 0; *decpt = k + 1; if (rve) *rve = s; return s0; } #ifdef __cplusplus } #endif
The thing is variable s is actually a char* so a string... This code is such a mess to read through.
|
Wall of code crits you for over 9000. You have died.
|
|
|
|