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?
Related
I have an example of a code and not sure what way is the best to use.
For example I have
if (x = 1) and (y = 2) and (if abc = false then check if z = 3) then
begin
...
check only
if x = 1
if y = 2
if abc = false check z = 3. if abc = true then dont check z = 3
i am not sure if i am explaining the best but hopefuly people will understand.
I want to know if this is possible or the best way to do it. Keeping in mind that rather than in example where its x, y, z and abc. there can be more in my use.
I currently have structure as...which i dont think is practical, and think theres a better way but i am not sure
if (abc = false) then
begin
if (x = 1) and (y = 2) and (z = 3) then
begin
...
end
else
begin
if (x = 1) and (y = 2) then
begin
...
Thanks in advance
I think you're looking for or. Now you will check that x must be 1, y must be 2, and if abc is false, z must be 3.
If abc = true, z can still be three, but it won't be checked.
Note that I just wrote abc instead of abc = true. Since it's a Boolean (true/false) already, that's allowed.
Also note how the operations are grouped using parentheses. The total sub-expression abc or (z=3) must return true for the total expression to return true.
Furthermore the sequence of the terms is significant - they are evaluated left-to-right. If the term (abc or (z=3)) is replaced by the logically-equivalent term ((z=3) or abc) then z=3 will be evaluated.
if (x = 1) and (y = 2) and (abc or (z = 3)) then
// Your magic goes here
Test program body to prove sequence is important
function z : Integer;
begin
writeln('Z being evaluated');
result := x + y;
end;
begin
x := 1;y := 2;
abc := true;
if (x=1) and (y=2) and (abc or (z=3)) then
writeln ('evaluated true')
else
writeln ('evaluated false');
writeln('done');
readln;
end.
Neither of your code samples compile, because neither is using the proper syntax.
This should get you started:
if (x = 1) and (y = 2) then
begin
if (abc) then
// Handle abc = True
else
begin
if (z = 3) then
// Handle abc = false and z = 3
else
// Handle abc = false and z <> 3
end;
end;
I have an output txtfile with some float numbers and I like to print in different formats, y try with:
FormatFloat('00000;000.0;00.00', val)
FormatFloat('00.00;000.0;00000', val)
But I take wrong outputs. What I need is:
If val < 10 then output like '00.00'
If 10 < val < 100 then output like '000.0'
If val > 100 then output like '00000'
It's a huge amount of float values, so, I need a low processing solution and I think more conditionals will slow down the application. ¿Any advice?
Thank you
Using conditional tests to sort the values into separate outputs is not going to affect performance in a significant way. The format process is far more elaborate. One important thing about optimization is to only walk that path if you can measure a performance hit in the actual code.
if (val < 10) then
s := FormatFloat('00.00',val)
else
if (val < 100) then
s := FormatFloat('000.0',val)
else
s := FormatFloat('00000',val);
Also consider using the thread-safe FormatFloat with a supplied FormatSettings variable.
I suppose that conditionals would work faster, but consider this sketch (care about out-of-range values):
const
FormatString: array[-1..2] of string = ('0.000', '0.00', '0.0', '0');
var
x: Double;
i: integer;
begin
x := 0.314;
for i := 1 to 4 do begin
Memo1.Lines.Add(FormatFloat(FormatString[Floor(Log10(x))], x));
x := x * 10;
end;
0.314
3.14
31.4
314
I have a problem with translating VHDL to Verilog.
It's part of my source code on VHDL.
With I/O I somehow understood, but have some problems to translate this string
ib1 <= std_logic_vector(to_unsigned(i,ib1'length));
to verilog?
COMPONENT GenerateModel
PORT(
ib1 : IN std_logic_vector(3 downto 0);
);
END COMPONENT;
--Inputs
signal ib1 : std_logic_vector(3 downto 0) := (others => '0');
BEGIN
uut: GenerateModel PORT MAP (
ib1 => ib1,
);
process
begin
for i in 0 to 15 loop
ib1 <= std_logic_vector(to_unsigned(i,ib1'length));
wait for 10 ns;
end loop;
end process;
end;
To extend into Verilog from Paebbels' comment, the line you are looking at does an explicit conversion from the type of the loop variable i to the port variable ib1. In Verilog, that explicit conversion is not needed, you can just assign the port variable directly. So, for example (in Verilog IEEE 1364-1995 compatible):
integer i;
...
for (i = 0; i < 16; i = i + 1) begin
ib1 = i; // <-- The line
#10; // -- Assume 1 step is 1 ns, can specific timescale if needed
end
If you want, you can even loop through the variable directly if its of type reg (ie, not a net):
for (ib1 = 0; ib1 < 15; ib1 = ib1 + 1) begin
#10;
end
#10;
[Note that as Greg mentioned, you need to be sure you dont create an infinite loop as if ib1 is 4-bits wide, it will always be less than 16, thus I fixed the example above to loop until ib1 is 15 (4'b1111)]
I am trying to create a line graph of an exponential function:
j:=IWcmbxCriterionName.ItemIndex;
p1a:=(-5000)*0.001;
p1c:= -(Exp(P1a * Min[j])) / (Exp(P1a * Max[j]) - Exp(P1a * Min[j]));
p1b := (1 - P1c) / Exp(P1a * Max[j]);
k1 := Max[j];
i1 := Min[j];
while i1 <= k1 do
begin
Serie1.AddXY(i1, P1b * Exp(p1a * (i1)) + p1c,'',clWebBLUE);
i1 := i1 + 0.01;
end;
chart1.BottomAxis.Maximum:=k1;
chart1.BottomAxis.Minimum:= min[j];
chart1.UndoZoom;
but the serie1 not appear on the graph! Can someone can help me?
Remove the lines where you set bottom axis min. and max. and try to set i to automatic just in case those values are wrong:
Chart1.BottomAxis.Automatic:=True;
If the problem persists please send us a simple example project we can run "as-is" to reproduce the problem here. You can post your files at our upload page.
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?