From: Ethan M. <merritt@u.washington.edu> - 2008-05-16 21:53:04
|
On Friday 16 May 2008 12:10, Lutz Maibaum wrote: > I encountered some issues when trying to use the mouse zoom on data sets > plotted on logarithmic axes. I have attached a sample data file. When I > start a new gnuplot session, and plot the data using > > set log x; set log y; plot "test.dat" u 1:2 w lp > > and then try to zoom into the top right corner of the plot, there is a good > chance that I get an error message along the lines of > > gnuplot> set xr[2645923.77833:105299864.051]; > set yr[525542494246:2.96579249916e+13]; set x2r[ 6.42110: 8.02058]; > set y2r[11.3442: 12.9336] > ^ > integer overflow; change to floating point > > I observed this in both the X11 and the wxt terminals, using gnuplot 4.2.3 > on a linux box. Can anyone else reproduce this behavior? No, I can't reproduce it. But I can see what is wrong from the output you gave. The zoom function reads off (x1,y1) and (x2,y2) coords from the mouse and constructs the appropriate "set [xy]range" commands as a string which is fed back to the command line interpreter. In your case the lower bound on y is too large to represent as an integer. This would normally be OK because it is written using a floating point format mouse.c line 662: sprintf(s, "set xr[%.12g:%.12g]; set yr[%.12g:%.12g]" but since there is nothing after the decimal point, the %g format writes it as a 12 digit integer. Such an integer is too large to read in. It would work if there were a trailing decimal point, but there isn't one. Simpler demonstation of the problem: gnuplot> t = 525542494246 gnuplot> print t 2147483647 gnuplot> t = 525542494246. gnuplot> print t 525542494246.0 Your machine issues the message you see "integer overflow; change to floating point". based on the test in scanner.c: get_num() lval = atol(str); if ((token[t_num].l_val.v.int_val = lval) != lval) But this test assumes appears to assume some odd non-POSIX behavior, and/or an odd compiler. I would expect the compiler to optimize away the test if ((A=B) != B) The only exception would be for A = NaN, but that can't happen for a positive integer. My linux machine behaves as documented by the spec for atol(). On overflow it returns MAX_LONG, which is a legal value, and the test for ((A=MAX_LONG) != MAX_LONG) can never trigger even if it hasn't been optimize away. Anyhow.... Can anyone think of a down-side to simply storing the number as a complex double in such a case? Does it even need to be treated as an int_error() rather than a simple warning? In a case like yours, even the warning is gratuitous. IOW, how about the following patch: --- gnuplot/src/scanner.c 2007-08-27 01:05:18.000000000 -0700 +++ gnuplot-cvs/src/scanner.c 2008-05-16 14:37:34.000000000 -0700 @@ -278,13 +278,16 @@ get_num(char str[]) while (isdigit((unsigned char) str[++count])); } if (token[t_num].l_val.type == INTGR) { - lval = atol(str); - if ((token[t_num].l_val.v.int_val = lval) != lval) - int_error(t_num, "integer overflow; change to floating point"); + token[t_num].l_val.v.int_val = atol(str); + if (token[t_num].l_val.v.int_val < INT_MAX) + return(count); + int_warn(t_num, "integer overflow; changing to floating point"); + token[t_num].l_val.type = CMPLX; + /* fall through */ } + + token[t_num].l_val.v.cmplx_val.imag = 0.0; + token[t_num].l_val.v.cmplx_val.real = atof(str); - } else { - token[t_num].l_val.v.cmplx_val.imag = 0.0; - token[t_num].l_val.v.cmplx_val.real = atof(str); return (count); } -- Ethan A Merritt |