I am writing a script to move an absolutely positioned element on a
page by a factor using style.top & style.left.
The amount to move by is always some fraction, so I was tossing up
between Math.ceil/floor and parseInt +/- 1 to ensure the amount to
move was at least 1 and in the right direction. I made a small test to
see which one is faster and also included simply adding/subtracting 1.
parseInt generally took 50% to 100% longer than Math.ceil/floor, but
adding/subtracting 1 is 30 to 100 times faster (depending on the
browser) than Math.ceil/floor. Naturally I'd like to use that since
it's so much quicker.
So my question is:
Is it safe to set the 'top' or 'left' of an element to some
fractional measurement of pixels?
e.g. is it safe to do:
x = 1.9863098
el.style.left = x + 'px'
or should I be making x an integer first (using parseInt or
Math.ceil/floor)? Here's my test script:
<form action="">
<input type="text" value="1000" name="num">Numb er of iterations<br>
<textarea name="outCell" rows="10" cols="30">
Click Run it to run it.
</textarea>
<input type="button" value="Run it" onclick="
// x will sometimes be +ve, sometimes -ve
var x = (Math.random()-0.5)*10;
var i, f, s, t0, t1;
i = this.form.num.v alue;
s = new Date();
while ( i-- ) {
( x>0 )? parseInt(x)+1 : parseInt(x)-1;
x += x;
}
f = new Date();
t0 = f-s;
i = this.form.num.v alue;
s = new Date();
while ( i-- ) {
( x>0 )? Math.ceil(x) : Math.floor(x);
x += x;
}
f = new Date();
t1 = f-s
i = this.form.num.v alue;
s = new Date();
while ( i-- ) {
( x>0 )? x+1 : x-1;
x += x;
}
f = new Date();
this.form.outCe ll.value =
'parseInt: ' + t0 + '\n'
+ 'ceil/floor: ' + t1 + '\n'
+ 'plus/minus: ' + (f-s)
;
">
</form>
--
Rob 6 8775
RobG wrote: I am writing a script to move an absolutely positioned element on a page by a factor using style.top & style.left.
The amount to move by is always some fraction, so I was tossing up between Math.ceil/floor and parseInt +/- 1 to ensure the amount to move was at least 1 and in the right direction. I made a small test to see which one is faster and also included simply adding/subtracting 1.
parseInt generally took 50% to 100% longer than Math.ceil/floor,
It would as parseInt type-converts non-string arguments into strings
prior to parsing them.
but adding/subtracting 1 is 30 to 100 times faster (depending on the browser)
Irrelevant if you have to do that anyway.
than Math.ceil/floor. Naturally I'd like to use that since it's so much quicker.
Subtraction is no substitute for rounding.
So my question is:
Is it safe to set the 'top' or 'left' of an element to some fractional measurement of pixels?
e.g. is it safe to do:
x = 1.9863098 el.style.left = x + 'px'
No. Many browsers will happily make pixel approximations of non-integer
values (they need to in order to cope with em, %, etc. units), but some
go belly up. It is much safer only to ask for pixel positions in
integers.
or should I be making x an integer first (using parseInt or Math.ceil/floor)?
<snip>
No. If you want to turn a number with a fractional part into an integer
suitable for use in positioning in the quickest way possible use:-
x | 0
- or:-
x >> 0
- as the bitwise operations truncate their operands to 32 bit signed
integer values (except for - >>> -, which uses ToUint32 internally
instead of ToInt32). 32 bit signed integers are sufficiently big to cove
all realistic pixel positioning and dimension requirements.
Generally, if you want fast math for pixel positioning work try to use
bitwise operators, particularly at the end of sequences of calculations.
For example, halving a dimension can be done as - ( x >> 1 ) - and be
guaranteed to return an integer result (so will not then need to be
floored), so:-
((totalWidth - elementWidth) >> 1)
- gives you a guaranteed integer result that is no bigger than half of
the width not taken up by elementWidth, ideal for centring an element in
a space, and without the need for further rounding.
<snip> i = this.form.num.v alue; s = new Date(); while ( i-- ) { ( x>0 )? parseInt(x)+1 : parseInt(x)-1;
<snip>
It is difficult for me to tell what you are after from this. My
inclination would be to handle distance and direction independently.
Acquiring a +1/-1 value for direction and a separate positive value for
distance. That allows the distance to be rounded in a known directions
(ie, truncated with bitwise operators, floored or ceiled) and then
direction applied by multiplication with +1/-1 (preserving the integer
nature of the result).
Many expressions can be used to give +1/-1 results based on
Math.random(), E.G.:-
Math.random()<0 .5 ? +1 : -1 // fastest on average, by a
// small margin
(((Math.random( )<0.5)&& +1)||-1)
((Math.random() +0.5)<<1)-1
((Math.random() <0.5)<<1)-1
So given a positive distance - d - that starts truncated/floored to an
integer, but must be made at least 1, and a direction - v -, that will
be either -1 or +1, you might have:-
(d + !d) * v
- where if - d - is non-zero - !d - is false, adding zero after
type-conversion to a number, and when - d - is zero - !d is true, adding
1 following type-conversion. Then the dimensions - d -,
truncated/floored and adjusted by one,if needed, only in one direction,
is multiplied by +1 or -1 to give an integer distance in one of two
opposite directions.
Richard.
Richard Cornford wrote: RobG wrote:
[...] Irrelevant if you have to do that anyway.
The strategy is to emulate ceil/floor, i.e. ensure that +ve numbers are
always 'rounded' up and -ve always 'rounded' down. This can be done by
adding 1 to +ve and subtracting 1 from -ve and truncating. The trick is
to do the logic for determining +ve/-ve, add/subtract and truncate with
the quickest algorithm.
I want numbers like 0.1 to become 1 (add 1 and truncate or use ceil) and
-0.1 to become -1 (subtract 1 and truncate or use floor).
It seems simply adding/subtracting and letting the browser truncate when
setting style.left/top is not reliable - small 'jitters' occur randomly
near the end of the movement, different browsers have different
behaviours. I was pretty sure I'd be told to pass integers. than Math.ceil/floor. Naturally I'd like to use that since it's so much quicker.
Subtraction is no substitute for rounding.
In the context described above, it kinda works, but not reliably, so I
guess you're right.
[...] No. Many browsers will happily make pixel approximations of non-integer values (they need to in order to cope with em, %, etc. units), but some go belly up. It is much safer only to ask for pixel positions in integers.
Agreed, and the results are inconsistent across browsers so it's a poor
strategy - unless unpredictable jitters with imprecise movement are
intended. :-) or should I be making x an integer first (using parseInt or Math.ceil/floor)?
<snip>
No. If you want to turn a number with a fractional part into an integer suitable for use in positioning in the quickest way possible use:-
x | 0
- or:-
x >> 0
- as the bitwise operations truncate their operands to 32 bit signed integer values (except for - >>> -, which uses ToUint32 internally instead of ToInt32). 32 bit signed integers are sufficiently big to cove all realistic pixel positioning and dimension requirements.
Here's my final version. moveBy is generated by some function of the
distance between two elements:
if ( moveBy ) {
setPos( obj, ((moveBy > 0)? ( moveBy+=1 | 0 ) : ( moveBy-=1 | 0 ) ));
}
It's neatly symmetrical, fast and +ve/-ve movement and truncating are
dealt with in one go.
Which is at least as fast as simply adding/subtracting one and is faster
by a factor of about 15 than the equivalent:
setPos( obj, ((moveBy > 0)? Math.ceil(moveB y) : Math.floor(move By))); Generally, if you want fast math for pixel positioning work try to use bitwise operators, particularly at the end of sequences of calculations. For example, halving a dimension can be done as - ( x >> 1 ) - and be guaranteed to return an integer result (so will not then need to be floored), so:-
((totalWidth - elementWidth) >> 1)
- gives you a guaranteed integer result that is no bigger than half of the width not taken up by elementWidth, ideal for centring an element in a space, and without the need for further rounding.
Yes, but I need to account for direction (+ve -ve) and would like to
have that done within a single step as above. <snip>
i = this.form.num.v alue; s = new Date(); while ( i-- ) { ( x>0 )? parseInt(x)+1 : parseInt(x)-1; <snip>
It is difficult for me to tell what you are after from this. My
It's just a test of part of my logic, on its own it's pretty
meaningless. ;-p
[...] Many expressions can be used to give +1/-1 results based on Math.random(), E.G.:-
Math.random()<0 .5 ? +1 : -1 // fastest on average, by a // small margin
(((Math.random( )<0.5)&& +1)||-1)
((Math.random() +0.5)<<1)-1
((Math.random() <0.5)<<1)-1
So given a positive distance - d - that starts truncated/floored to an integer, but must be made at least 1, and a direction - v -, that will be either -1 or +1, you might have:-
(d + !d) * v
- where if - d - is non-zero - !d - is false, adding zero after type-conversion to a number, and when - d - is zero - !d is true, adding 1 following type-conversion. Then the dimensions - d -, truncated/floored and adjusted by one,if needed, only in one direction, is multiplied by +1 or -1 to give an integer distance in one of two opposite directions.
Actually I'm trying to avoid random movement (!) but thanks for the tip,
I'm sure it will come in handy.
--
Rob
RobG wrote:
<snip> Here's my final version. moveBy is generated by some function of the distance between two elements:
if ( moveBy ) { setPos( obj, ((moveBy > 0)? ( moveBy+=1 | 0 ) : ( moveBy-=1 | 0 ) )); }
<snip>
In looking at this I observe that the value that is determined by the
outcome of the conditional expression is the +/-1, so maybe;-
setPos( obj, ((moveBy += ((moveBy > 0)?1:-1)) | 0) )
Richard.
Richard Cornford wrote: RobG wrote: <snip>
Here's my final version. moveBy is generated by some function of the distance between two elements:
if ( moveBy ) { setPos( obj, ((moveBy > 0)? ( moveBy+=1 | 0 ) : ( moveBy-=1 | 0 ) )); }
<snip>
In looking at this I observe that the value that is determined by the outcome of the conditional expression is the +/-1, so maybe;-
setPos( obj, ((moveBy += ((moveBy > 0)?1:-1)) | 0) )
And the outer bit-wise truncates - sweet!
--
Rob
JRS: In article <Hq************ ******@news.opt us.net.au>, dated Fri, 8
Jul 2005 01:13:11, seen in news:comp.lang. javascript, RobG
<rg***@iinet.ne t.auau> posted : Richard Cornford wrote: RobG wrote: <snip>
Here's my final version. moveBy is generated by some function of the distance between two elements:
if ( moveBy ) { setPos( obj, ((moveBy > 0)? ( moveBy+=1 | 0 ) : ( moveBy-=1 | 0 ) )); }
<snip>
In looking at this I observe that the value that is determined by the outcome of the conditional expression is the +/-1, so maybe;-
setPos( obj, ((moveBy += ((moveBy > 0)?1:-1)) | 0) )
And the outer bit-wise truncates - sweet!
If you are repeatedly moving in the same direction by
function(distan ce), then the direction should be determined, for speed,
outside the move loop. Possibly, write a function to move +, another to
move -, and at the start of each sequence assign one or other to do the
job; but function calls may be slower.
If you are using new Date() to time your moves, you probably need not
care much about the speed of the move calculation code, depending on OS;
unless the OS maintains and serves the date as a day- or seconds- count,
there's more work in new Date() than there can be in move-calculation.
And, between ticks, one can calculate a lot.
Timing with setTimeout or setInterval would not have those overheads,
but different ones.
--
© John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
<URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
<URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Dr John Stockton wrote: JRS: In article <Hq************ ******@news.opt us.net.au>, dated Fri, 8 Jul 2005 01:13:11, seen in news:comp.lang. javascript, RobG <rg***@iinet.ne t.auau> posted :
Richard Cornford wrote:
RobG wrote: <snip>
Here's my final version. moveBy is generated by some function of the distance between two elements:
if ( moveBy ) { setPos( obj, ((moveBy > 0)? ( moveBy+=1 | 0 ) : ( moveBy-=1 | 0 ) )); }
<snip>
In looking at this I observe that the value that is determined by the outcome of the conditional expression is the +/-1, so maybe;-
setPos( obj, ((moveBy += ((moveBy > 0)?1:-1)) | 0) )
And the outer bit-wise truncates - sweet!
If you are repeatedly moving in the same direction by function(distan ce), then the direction should be determined, for speed, outside the move loop. Possibly, write a function to move +, another to move -, and at the start of each sequence assign one or other to do the job; but function calls may be slower.
Thanks, I'll consider that.
The destination can move before it is reached, therefore position and
distance are calculated each time after a move. I am working on
creating objects that learn to move of their own accord - accelerate,
move with a set speed, then decelerate. But they also need to be
updated with where the destination has moved to as they go.
My biggest speed issue is eliminating the use of Math functions. They
are handy to use to get the logic right, but then optimisation is
required - using a function that is 30 times faster frees-up quite a
bit of CPU! If you are using new Date() to time your moves, you probably need not care much about the speed of the move calculation code, depending on OS; unless the OS maintains and serves the date as a day- or seconds- count, there's more work in new Date() than there can be in move-calculation. And, between ticks, one can calculate a lot.
I was using a date object to time sections of code - usually 10,000 or
so loops with multiple runs are required to get meaningful results.
I've also found that when testing a series loops in a single function,
going first is a distinct disadvantage. Timing with setTimeout or setInterval would not have those overheads, but different ones.
--
Rob This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Tom |
last post by:
Has anyone ever seen a IComparer for floats the returns magnitude.
i.e. instead of returning -1, it would return -5. To let you know HOW
different the two numbers are. obviously for int it is a - b. But for
float the results would have to be normalize some how to a 32bit
range. I understand there would be percision errors.
Thanks
Tom
|
by: limelight |
last post by:
I have discovered a math error in the .NET framework's Log function. It
returns incorrect results for varying powers of 2 that depend on whether the
program is run from within the IDE or from the command line. The amount by
which the calculation is off is very small; even though the double data type
holds the errant value, it seems to round off when printed (via ToString())
and shows the correct one. The problem is that the errant value is...
|
by: Henke |
last post by:
I wanna round an value in a javascript Down to nearest hundred.
For example: 3234 = 3200 and 3890 = 3800
Always down and to hundred.
I have tried Math.floor but that just round down to ten.
Is there any way 2 do this??
Regards
/Henke
|
by: Gabest |
last post by:
I was doing a rasterizer when noticed how slow ceil was. What I found was
rather interesting, see my report for more detail:
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=62c7e74e-5f18-4b40-81dc-f6231a45c4a4
Since floor turned out to be that fast, I have even replaced fmod with num -
floor(num) in my code. It does not give correct results for negative numbers
of course, but to get the coefficient for...
|
by: mikael.liljeroth |
last post by:
Why do I get NO as result from this ??
double du = (double)3.1415;
du = ceil(du);
if(du == (double)4)
printf("YES\n");
else
printf("NO\n");
| |
by: bravesplace |
last post by:
Hello,
I am using the folling funtion to round a number to a single digit on
my form:
function round1(num)
{
return Math.round(num*1)/1
}
|
by: Gregory Pietsch |
last post by:
I'm writing a portable implementation of the C standard library for
http://www.clc-wiki.net and I was wondering if someone could check the
functions in math.h for sanity/portability/whatever. I'm almost halfway
through writing the over 200 functions needed to implement C99's
version of math.h, and I would like to have some feedback and/or expert
advice on my implementations.
Sincerely, Gregory Pietsch
|
by: Ken Fine |
last post by:
Hi there,
I have written a simple function that attempts to set the angle of objects
so as to place them in aesthetically appealing ways. The code follows; there
is some stupidness in it (e.g. a test for meaningless <=180 as a boolean
test). The function is designed to return values that will avoid positioning
things a) upside down and b) at "too steep" an angle.
I would now like to know how I could write my function so that the...
|
by: matthias s |
last post by:
Hi there,
I believed that Math.Ceiling is like Math.Round except that it always rounds
up to the next
but this
double d = Math.Ceiling(29/15);
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |