newValue := oldValue;
repeat
delta := (RandomRange(0, 200) / 100) - 1;
newValue := newValue + delta;
until (newValue > 24) and (newValue < 40);
oldValue := newValue;
newValue2 := oldValue2;
repeat
delta := (RandomRange(0, 200) / 100) - 1;
newValue2 := newValue2 + delta;
until (newValue2 > 24) and (newValue2 < 40) and (newValue2 < newValue);
oldValue2 := newValue2;
after a few iterations, this hits an endless loop in the second loop. It is meant to change a Float randomly by -1 to +1 and keep it in the range 24 to 40 while still being less than another Float which is being randomly changed in the same way.
Who can be first to make me say "d'oh!"? (probably by (newValue2 < newValue))
d'oh!
Well, now that it is pointed out, the answer is obvious. newValue := oldValue + delta;, not ` newValue := newValue + delta;', so that the code reads (similar for both loops)
newValue := oldValue;
repeat
delta := (RandomRange(0, 200) / 100) - 1;
newValue := oldValue + delta; <==== **NOT** newValue
until (newValue > 24) and (newValue < 40);
oldValue := newValue;
Thanks, all, and lots of +1 all round
What do you mean by "keep it in the range 24 to 40"? Your condition "until (newValue > 24) and (newValue < 40)" implies that it will stop once it is in that range; it will go forever if it is outside that range.
The chances of it terminating depend upon oldValue. What values are you expecting oldValue to have?
In any case, such a loop is not guaranteed to terminate. You are changing the number randomly each time, so there is no guarantee it will move into the termination range at all. In particular, a large number of random numbers between -1 and 1 all added together will usually sum to approximately 0, so you can't expect the number to change significantly over time. It's probably the case that it happens never to enter that range.
You set the value of oldValue twice, once after each loop. It looks like you really want to set the value of oldValue2 after the second loop.
I'm not a delphi person so I could be way off (and I'll delete my answer if someone tells me I am)
but won't the delta just as likely be away from zero negatively as it will be positively on each iteration. Or simplified just as likely to be -1 as it is +1.
If this is true won't the value of newValue over many iteration have almost no change?
Update
Or to clarify won't the sum of a lot of random numbers between -1 and 1 be very near zero.
In any case wouldn't be simpler to create a variable to hold the number of iterationsyou might want.
e.g.
repeatcount:= RandomRange(24,40)
num:0
repeat
num := num +1
until (num = repeatcount)
or if you just want new value to be somewhere between 24 and 40
newValue := Random(24,40)
While i don't know Delphi, I wonder what's going on with the RandomRange function. The way its written, it looks as though RandomRange is getting you a number from 0 to 200, which you are then dividing by 100 to get a number from 0 to 2. Then, you subtract 1, getting a number from -1 to 1. If I read it correctly, then you the value should stay just about the same over time.
What do you get if you trace the values in the loop conditions?
Related
This is (supposed to be) a function which makes sure that the the sum of a number of slider's values always adds up to globalTotal.
A slider value can be changed manually by the user to changer.value and then when applying this function to the values of the other sliders, it can determine their new or endVal.
It takes the startVal of the slider which needs changing and the original value of the slider that changed changerStartVal and can determine the new value others by weighting.
The problem and my question is. Sometimes remainingStartVals can be zero (when the slider changing gets moved all the way to maximum) or startVal can be zero (when the slider changing is moved to zero and then another slider is moved). When this happens I get a divide-by-zero or a multiply-by-zero respectively. Both of which are bad and lead to incorrect results. Is there an easy way to fix this?
func calcNewVal(startVal: Float, changerStartVal: Float) -> Float {
let remainingStartVals = globalTotal - changerStartVal
let remainingNewVals = globalTotal - changer.value
let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
return endVal
}
This is a mathematical problem, not a problem related to Swift or any specific programming language so I'll answer with mathematical formulas and explanations rather than code snippets.
I don't really understand your algorithm either. For example in this line:
let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
you first multiply by 100 and then divide by 100, so you could just leave all these 100 factors out in the first place!
However, I think I understand what you're trying to achieve and the problem is that there is no generic solution. Before writing an algorithm you have to define exactly how you want it to behave, including all edge cases.
Let's define:
vi as the value of the i-th slider and
Δi as the change of the i-th slider's value
Then you have to think of the following cases:
Case 1:
0 < vi ≤ 1 for all sliders (other than the one you changed)
This is probably the common case you were thinking about. In this case you want to adjust the values of your unchanged sliders so that their total change is equal to the change Δchanged of the slider you changed. In other words:
∑i Δi = 0
If you have 3 sliders this reduces to:
Δ1 + Δ2 + Δ3 = 0
And if the slider that changed is the one with i = 1 then this requirement would read:
Δ1 = – (Δ2 + Δ3)
You want the sliders to adjust proportionally which means that this change Δ1 should not be distributed equally on the other sliders but depending on their current value:
Δ2 = – w2 * Δ1
Δ3 = – w3 * Δ1
The normed weight factors are
w2 = v2 / (v2 + v3)
w3 = v3 / (v2 + v3)
Thus we get:
Δ2 = – v2 / (v2 + v3) * Δ1
Δ3 = – v3 / (v2 + v3) * Δ1
So these are the formulas to applied for this particular case.
However, there are quite a few other cases that don't work with this approach:
Case 2:
vi = 0 for at least one, but not all of the sliders (other than the one you changed)
In this case the approach from case 1 would still work (plus it would be the logical thing to do). However, a slider's value would never change if it's zero. All of the change will be distributed over the sliders with a value > 0.
Case 3:
vi = 0 for all sliders (other than the one you changed)
In this case the proportional change doesn't work because there is simply no information how to distribute the change over the sliders. They're all zero! This is actually your zero division problem: In the case where we have 3 sliders and the slider 1 changes we'll get
v2 + v3 = 0
This is only another manifestation of the fact that the weight factors wi are simply undefined. Thus, you'll have to manually define what will happen in this case.
The most plausible thing to do in this case is to distribute the change evenly over all sliders:
Δi = – (1 / n) * Δ1
where n is the number of sliders (excluding the one that was changed!). With this logic, every slider gets "the same share" of the change.
Now that we're clear with our algorithm you can implement these cases in code. Here some pseudo code as an example:
if sum(valuesOfAllSlidersOtherThanTheSliderThatChanged) == 0 {
for allUnchangedSliders {
// distribute change evenly over the sliders
Δi = – (1 / n) * Δ_changedSlider
}
}
else {
for allUnchangedSliders {
// use weight factor to change proportionally
Δi = – v_i / ∑(v_i) * Δ_changedSlider
}
}
Please be aware that you must cache the values of the current state of your sliders at the beginning or (even better) first compute all the changes and then apply all the changes in a batch. Otherwise you will use a value v2' that you just computed for determining the value v3' which will obviously result in incorrect values.
Hey #Sean the simplest adjustment that I could think of here is to check if the remainingStartVals is not 0 that means that there are weights assigned to the other sliders and also check if a single slider had a weight to begin with which means its startVal shouldn't be equal to 0
func calcNewVal(startVal: Float, changerStartVal: Float) -> Float{
var endVal = 0
let remainingStartVals = globalTotal - changerStartVal
if remainingStartVals != 0 || startVal != 0{
let remainingNewVals = globalTotal - changer.value
endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
}
return endVal
}
I am playing around with the KMP algorithm in f sharp. While it works for patterns like "ATAT" (result will be [|0; 0; 1; 2;|]) , the first while loop enters a deadlock when the first 2 characters of a string are the same and the 3rd is another, for example "AAT".
I understand why: first, i gets incremented to 1. now the first condition for the while loop is true, while the second is also true, because "A" <> "T". Now it sets i to prefixtable.[!i], which is 1 again, and here we go.
Can you guys give me a hint on how to solve this?
let kMPrefix (pattern : string) =
let (m : int) = pattern.Length - 1
let prefixTable = Array.create pattern.Length 0
// i : longest proper prefix that is also a suffix
let i = ref 0
// j: the index of the pattern for which the prefix value will be calculated
// starts with 1 because the first prefix value is always 0
for j in 1 .. m do
while !i > 0 && pattern.[!i] <> pattern.[j] do
i := prefixTable.[!i]
if pattern.[!i] = pattern.[j] then
i := !i+1
Array.set prefixTable j !i
prefixTable
I'm not sure how to repair the code with a small modification, since it doesn't match the KMP algorithm's lookup table contents (at least the ones I've found on Wikipedia), which are:
-1 for index 0
Otherwise, the count of consecutive elements before the current position that match the beginning (excluding the beginning itself)
Therefore, I'd expect output for "ATAT" to be [|-1; 0; 0; 1|], not [|0; 0; 1; 2;|].
This type of problem might be better to reason about in functional style. To create the KMP table, you could use a recursive function that fills the table one by one, keeping track of how many recent characters match the beginning, and start running it at the second character's index.
A possible implementation:
let buildKmpPrefixTable (pattern : string) =
let prefixTable = Array.zeroCreate pattern.Length
let rec run startIndex matchCount =
let writeIndex = startIndex + matchCount
if writeIndex < pattern.Length then
if pattern.[writeIndex] = pattern.[matchCount] then
prefixTable.[writeIndex] <- matchCount
run startIndex (matchCount + 1)
else
prefixTable.[writeIndex] <- matchCount
run (writeIndex + 1) 0
run 1 0
if pattern.Length > 0 then prefixTable.[0] <- -1
prefixTable
This approach isn't in danger of any endless loops/recursion, because all code paths of run either increase writeIndex in the next iteration or finish iterating.
Note on terminology: the error you are describing in the question is an endless loop or, more generally, non-terminating iteration. Deadlock refers specifically to a situation in which a thread waits for a lock that will never be released because the thread holding it is itself waiting for a lock that will never be released for the same reason.
I have a few values
Quantity := 5;
Quantity2 := 8;
percent :=50;
so i want
Percent of Quantity + Quantity 2
which would be like : 50% of 13 = 6.5
I done it like this
HowMuchDamage := trunc(percent*(Quantity + Quantity2)/100);
How can i make it round up?
How can i make it round down?
Floor(X) returns the highest integer less than or equal to X.
Ceil(X) returns the lowest integer greater than or equal to X.
How we can generate randomize number between a range in the Float numbers (in delphi xe3) ?
For example, randomize number between [0.10 to 0.90].
I need give results like:
[ 0.20 , 0.32 , 0.10 , 0.50 ]
Thanks for solutions....
Another option is to use RandomRange (returns: AFrom <= r < ATo) as follow:
RandomRange(10, 90 + 1) / 100
or
RandomRange(10, 90 + 1) * 0.01
will return numbers in the range of 0.10 to 0.90 (including 0.90)
var
float : Double;
float := Random; // Random float in range: 0 <= float < 1
float := 0.1 + float*0.8 // 0.1 <= float < 0.9
To initialize the Random number generator, make a single call to Randomizeor set the RandSeed parameter before calling the Random function for the first time.
Not doing so, generates the same sequence every time you run the program. Note however, that this sequence is not guaranteed when recompiling for another compiler version.
Try this:
function RandomRangeF(min, max: single): single;
begin
result := min + Random * (max - min);
end;
This is a bit cheeky but here goes: Depends how many numbers you want after the floating point. For example, if you want 1 number, you could generate in the 100 - 999 range and then divide by 10. Or 1000 - 9999 and divide by 100.
I found that a nested loop fails when some particular condition is reached, somehow when I = 1, J = 3 and k = 5
I tried to right click on the breakpoint and in the condition I set
(I = 1) and (J = 3) AND (K = 5)
anyway the breakpoint doesn't stop...
What is wrong?
I've just tried that in D2007 and it works fine. what version are you using?
procedure TForm85.FormClick(Sender: TObject);
var i,j,k : integer;
z:integer;
begin
for i := 0 to 10 do
for j := 0 to 10 do
for k := 0 to 10 do
BEGIN
z := z + i * j * k; // breakpoint on this line.
END;
ShowMessage(IntToStr(z));
end;
Have you considered that the breakpoint may not be reached because the condition is not being met?
You did add the breakpoint as a Breaking breakpoint I assume.
To verify this
open the Breakpoint properties window
click on Advanced
make sure the Break checkbox is checked.
May be according to your code
(I = 1) and (J = 3) AND (K = 5)
may never get this values at same time
Set breakpoint on a line of code before the condition is met and step through with F8?