Case 956

Two safe changes made two stops

two_safe_changes_made_two_stops.eml - A photographer metered a portrait at f/8 and 1/125, opened the aperture one stop to soften the background, and slowed the shutter one stop as well, to be safe in the shade. Each change was one careful stop. What two careful stops in the same direction add up to is computed below.

ok: true — round-trip fixpoint reached (python1 == python2)updated 2026-09-21

EML

eml
# Self-authored for the EML case corpus (no external origin). A photographer
# metered a portrait at f/8 and 1/125, opened the aperture one stop to soften
# the background, and slowed the shutter one stop as well, to be safe in the
# shade. Each change was one careful stop. What two careful stops in the same
# direction add up to is computed below.
#
# The reasoning is careful. The meter reading was right; one stop of aperture
# is a real, standard step; one stop of shutter is a real, standard step; both
# were chosen deliberately; and the intent was exactly 'a softer background,
# safely exposed'.
#
# Exposure is aperture times time, and stops are doublings on both dials, so a
# stop opened and a stop slowed do not add caution - they multiply the light by
# two and by two again, four times the metered exposure, where f/5.6 at 1/250
# or f/11 at 1/60 would each have held it exactly.

8 => metered_f_number_label
125 => metered_shutter_denominator
1 => stops_the_aperture_was_opened
1 => stops_the_shutter_was_slowed

2^1 => light_multiplier_from_opening_one_stop
2^1 => time_multiplier_from_slowing_one_stop
light_multiplier_from_opening_one_stop * time_multiplier_from_slowing_one_stop => exposure_multiplier_of_the_two_safe_changes
stops_the_aperture_was_opened + stops_the_shutter_was_slowed => stops_over_the_meter

int(light_multiplier_from_opening_one_stop / time_multiplier_from_slowing_one_stop) => exposure_multiplier_open_one_and_faster_one
int(time_multiplier_from_slowing_one_stop / light_multiplier_from_opening_one_stop) => exposure_multiplier_close_one_and_slower_one
2^2 => light_multiplier_from_opening_two_stops
2^2 => time_divisor_from_two_stops_faster
int(light_multiplier_from_opening_two_stops / time_divisor_from_two_stops_faster) => exposure_multiplier_open_two_and_faster_two
exposure_multiplier_of_the_two_safe_changes - exposure_multiplier_open_one_and_faster_one => excess_light_as_a_multiple_of_the_metered_exposure

"metered                         : f/" + str(metered_f_number_label) + " at 1/" + str(metered_shutter_denominator) ^0
"change one                      : aperture opened " + str(stops_the_aperture_was_opened) + " stop, to f/5.6, light times " + str(light_multiplier_from_opening_one_stop) ^0
"change two                      : shutter slowed " + str(stops_the_shutter_was_slowed) + " stop, to 1/60, time times " + str(time_multiplier_from_slowing_one_stop) ^0
"together                        : exposure times " + str(exposure_multiplier_of_the_two_safe_changes) + ", " + str(stops_over_the_meter) + " stops over the meter" ^0
"" ^0
"settings that hold the meter    :" ^0
"  f/5.6 at 1/250                : open one, faster one, exposure times " + str(exposure_multiplier_open_one_and_faster_one) ^0
"  f/11 at 1/60                  : close one, slower one, exposure times " + str(exposure_multiplier_close_one_and_slower_one) ^0
"  f/4 at 1/500                  : open two, faster two, exposure times " + str(exposure_multiplier_open_two_and_faster_two) ^0
"  f/5.6 at 1/60                 : open one, slower one, exposure times " + str(exposure_multiplier_of_the_two_safe_changes) + " - the one chosen" ^0
"excess light                    : " + str(excess_light_as_a_multiple_of_the_metered_exposure) + " metered exposures on top of the one wanted" ^0
"" ^0

# ---- what the photographer verified ----

"the two-careful-stops reasoning" ^0
"  meter : right, f/" + str(metered_f_number_label) + " at 1/" + str(metered_shutter_denominator) ^0
"  aperture : one standard stop, for the background" ^0
"  shutter : one standard stop, for safety in the shade" ^0
"  intent : a softer background, safely exposed" ^0
"  facts wrong : 0" ^0
"  verdict : ONE STOP EACH IS CAREFUL" ^0
"" ^0
"  moving each dial by exactly one standard stop is the part" ^0
"  done right here, and it is why each change alone is a" ^0
"  clean doubling and nothing stranger" ^0
"" ^0

# ---- what two stops the same way add up to ----

"stops multiply" ^0
"  exposure : light through the aperture, times the time it is open" ^0
"  a stop on either dial : a doubling or a halving of that" ^0
"  a stop opened and a stop faster : times " + str(light_multiplier_from_opening_one_stop) + " and over " + str(time_multiplier_from_slowing_one_stop) + ", the" ^0
"    meter held; that is what the reciprocal settings are" ^0
"  a stop opened and a stop slowed : times " + str(light_multiplier_from_opening_one_stop) + " and times " + str(time_multiplier_from_slowing_one_stop) + "," ^0
"    " + str(exposure_multiplier_of_the_two_safe_changes) + " times the meter" ^0
"  what 'to be safe' bought : a second doubling on top of" ^0
"    the first, in the same direction" ^0
"" ^0

# ---- what the photographer got ----

"the portrait" ^0
"  believed : soft background, exposure on the safe side" ^0
"  actual : " + str(stops_over_the_meter) + " stops over, " + str(exposure_multiplier_of_the_two_safe_changes) + " times the light the meter asked for" ^0
"  was either stop wrong : no; each was a clean standard step" ^0
"  were they safe together : no; safety on one dial is paid for" ^0
"    on the other, and both were spent the same way" ^0
"" ^0

# ---- null control ----

# The same softer background bought with the aperture and paid for with the
# shutter, instead of bought on both dials.
4 => nc_exposure_multiplier_opening_and_slowing
1 => nc_exposure_multiplier_opening_and_speeding_up
3 => nc_excess_exposures_the_reciprocal_change_avoids

"null control - pay for the aperture on the shutter" ^0
"  exposure multiplier, opening and slowing : " + str(nc_exposure_multiplier_opening_and_slowing) ^0
"  exposure multiplier, opening and speeding up : " + str(nc_exposure_multiplier_opening_and_speeding_up) ^0
"  excess exposures the reciprocal change avoids : " + str(nc_excess_exposures_the_reciprocal_change_avoids) ^0
"  no meter and no lens changed; the second dial was moved to" ^0
"  cancel the first instead of to echo it" ^0
"" ^0

# ---- the rule ----

"what two exact one-stop changes guarantee" ^0
"  each dial moved by exactly one doubling : exactly" ^0
"  the exposure stayed near the meter : not addressed; the" ^0
"    doublings multiply, and two in the same direction make" ^0
"    " + str(exposure_multiplier_of_the_two_safe_changes) + " times the metered light, " + str(stops_over_the_meter) + " stops over" ^0
"" ^0

"caution on one dial is a debt owed on the other; spend it twice in the same" ^0
"direction and you have not been careful two times but generous four" ^0
"" ^0

"Each change was one exact stop - that part is clean. But exposure multiplies" ^0
"the two dials, so opening one and slowing one is " + str(light_multiplier_from_opening_one_stop) + " times " + str(time_multiplier_from_slowing_one_stop) + ", " + str(exposure_multiplier_of_the_two_safe_changes) + " times" ^0
"the meter and " + str(stops_over_the_meter) + " stops over, where f/5.6 at 1/250 holds it at " + str(exposure_multiplier_open_one_and_faster_one) + ", until the" ^0
"second dial is moved to pay for the first rather than to repeat it." ^0

Python (deterministic transpilation)

python
metered_f_number_label = 8
metered_shutter_denominator = 125
stops_the_aperture_was_opened = 1
stops_the_shutter_was_slowed = 1
light_multiplier_from_opening_one_stop = 2**1
time_multiplier_from_slowing_one_stop = 2**1
exposure_multiplier_of_the_two_safe_changes = light_multiplier_from_opening_one_stop * time_multiplier_from_slowing_one_stop
stops_over_the_meter = stops_the_aperture_was_opened + stops_the_shutter_was_slowed
exposure_multiplier_open_one_and_faster_one = int(light_multiplier_from_opening_one_stop / time_multiplier_from_slowing_one_stop)
exposure_multiplier_close_one_and_slower_one = int(time_multiplier_from_slowing_one_stop / light_multiplier_from_opening_one_stop)
light_multiplier_from_opening_two_stops = 2**2
time_divisor_from_two_stops_faster = 2**2
exposure_multiplier_open_two_and_faster_two = int(light_multiplier_from_opening_two_stops / time_divisor_from_two_stops_faster)
excess_light_as_a_multiple_of_the_metered_exposure = exposure_multiplier_of_the_two_safe_changes - exposure_multiplier_open_one_and_faster_one
print("metered                         : f/" + str(metered_f_number_label) + " at 1/" + str(metered_shutter_denominator))
print("change one                      : aperture opened " + str(stops_the_aperture_was_opened) + " stop, to f/5.6, light times " + str(light_multiplier_from_opening_one_stop))
print("change two                      : shutter slowed " + str(stops_the_shutter_was_slowed) + " stop, to 1/60, time times " + str(time_multiplier_from_slowing_one_stop))
print("together                        : exposure times " + str(exposure_multiplier_of_the_two_safe_changes) + ", " + str(stops_over_the_meter) + " stops over the meter")
print("")
print("settings that hold the meter    :")
print("  f/5.6 at 1/250                : open one, faster one, exposure times " + str(exposure_multiplier_open_one_and_faster_one))
print("  f/11 at 1/60                  : close one, slower one, exposure times " + str(exposure_multiplier_close_one_and_slower_one))
print("  f/4 at 1/500                  : open two, faster two, exposure times " + str(exposure_multiplier_open_two_and_faster_two))
print("  f/5.6 at 1/60                 : open one, slower one, exposure times " + str(exposure_multiplier_of_the_two_safe_changes) + " - the one chosen")
print("excess light                    : " + str(excess_light_as_a_multiple_of_the_metered_exposure) + " metered exposures on top of the one wanted")
print("")
print("the two-careful-stops reasoning")
print("  meter : right, f/" + str(metered_f_number_label) + " at 1/" + str(metered_shutter_denominator))
print("  aperture : one standard stop, for the background")
print("  shutter : one standard stop, for safety in the shade")
print("  intent : a softer background, safely exposed")
print("  facts wrong : 0")
print("  verdict : ONE STOP EACH IS CAREFUL")
print("")
print("  moving each dial by exactly one standard stop is the part")
print("  done right here, and it is why each change alone is a")
print("  clean doubling and nothing stranger")
print("")
print("stops multiply")
print("  exposure : light through the aperture, times the time it is open")
print("  a stop on either dial : a doubling or a halving of that")
print("  a stop opened and a stop faster : times " + str(light_multiplier_from_opening_one_stop) + " and over " + str(time_multiplier_from_slowing_one_stop) + ", the")
print("    meter held; that is what the reciprocal settings are")
print("  a stop opened and a stop slowed : times " + str(light_multiplier_from_opening_one_stop) + " and times " + str(time_multiplier_from_slowing_one_stop) + ",")
print("    " + str(exposure_multiplier_of_the_two_safe_changes) + " times the meter")
print("  what 'to be safe' bought : a second doubling on top of")
print("    the first, in the same direction")
print("")
print("the portrait")
print("  believed : soft background, exposure on the safe side")
print("  actual : " + str(stops_over_the_meter) + " stops over, " + str(exposure_multiplier_of_the_two_safe_changes) + " times the light the meter asked for")
print("  was either stop wrong : no; each was a clean standard step")
print("  were they safe together : no; safety on one dial is paid for")
print("    on the other, and both were spent the same way")
print("")
nc_exposure_multiplier_opening_and_slowing = 4
nc_exposure_multiplier_opening_and_speeding_up = 1
nc_excess_exposures_the_reciprocal_change_avoids = 3
print("null control - pay for the aperture on the shutter")
print("  exposure multiplier, opening and slowing : " + str(nc_exposure_multiplier_opening_and_slowing))
print("  exposure multiplier, opening and speeding up : " + str(nc_exposure_multiplier_opening_and_speeding_up))
print("  excess exposures the reciprocal change avoids : " + str(nc_excess_exposures_the_reciprocal_change_avoids))
print("  no meter and no lens changed; the second dial was moved to")
print("  cancel the first instead of to echo it")
print("")
print("what two exact one-stop changes guarantee")
print("  each dial moved by exactly one doubling : exactly")
print("  the exposure stayed near the meter : not addressed; the")
print("    doublings multiply, and two in the same direction make")
print("    " + str(exposure_multiplier_of_the_two_safe_changes) + " times the metered light, " + str(stops_over_the_meter) + " stops over")
print("")
print("caution on one dial is a debt owed on the other; spend it twice in the same")
print("direction and you have not been careful two times but generous four")
print("")
print("Each change was one exact stop - that part is clean. But exposure multiplies")
print("the two dials, so opening one and slowing one is " + str(light_multiplier_from_opening_one_stop) + " times " + str(time_multiplier_from_slowing_one_stop) + ", " + str(exposure_multiplier_of_the_two_safe_changes) + " times")
print("the meter and " + str(stops_over_the_meter) + " stops over, where f/5.6 at 1/250 holds it at " + str(exposure_multiplier_open_one_and_faster_one) + ", until the")
print("second dial is moved to pay for the first rather than to repeat it.")

stdout (executed)

text
metered                         : f/8 at 1/125
change one                      : aperture opened 1 stop, to f/5.6, light times 2
change two                      : shutter slowed 1 stop, to 1/60, time times 2
together                        : exposure times 4, 2 stops over the meter

settings that hold the meter    :
  f/5.6 at 1/250                : open one, faster one, exposure times 1
  f/11 at 1/60                  : close one, slower one, exposure times 1
  f/4 at 1/500                  : open two, faster two, exposure times 1
  f/5.6 at 1/60                 : open one, slower one, exposure times 4 - the one chosen
excess light                    : 3 metered exposures on top of the one wanted

the two-careful-stops reasoning
  meter : right, f/8 at 1/125
  aperture : one standard stop, for the background
  shutter : one standard stop, for safety in the shade
  intent : a softer background, safely exposed
  facts wrong : 0
  verdict : ONE STOP EACH IS CAREFUL

  moving each dial by exactly one standard stop is the part
  done right here, and it is why each change alone is a
  clean doubling and nothing stranger

stops multiply
  exposure : light through the aperture, times the time it is open
  a stop on either dial : a doubling or a halving of that
  a stop opened and a stop faster : times 2 and over 2, the
    meter held; that is what the reciprocal settings are
  a stop opened and a stop slowed : times 2 and times 2,
    4 times the meter
  what 'to be safe' bought : a second doubling on top of
    the first, in the same direction

the portrait
  believed : soft background, exposure on the safe side
  actual : 2 stops over, 4 times the light the meter asked for
  was either stop wrong : no; each was a clean standard step
  were they safe together : no; safety on one dial is paid for
    on the other, and both were spent the same way

null control - pay for the aperture on the shutter
  exposure multiplier, opening and slowing : 4
  exposure multiplier, opening and speeding up : 1
  excess exposures the reciprocal change avoids : 3
  no meter and no lens changed; the second dial was moved to
  cancel the first instead of to echo it

what two exact one-stop changes guarantee
  each dial moved by exactly one doubling : exactly
  the exposure stayed near the meter : not addressed; the
    doublings multiply, and two in the same direction make
    4 times the metered light, 2 stops over

caution on one dial is a debt owed on the other; spend it twice in the same
direction and you have not been careful two times but generous four

Each change was one exact stop - that part is clean. But exposure multiplies
the two dials, so opening one and slowing one is 2 times 2, 4 times
the meter and 2 stops over, where f/5.6 at 1/250 holds it at 1, until the
second dial is moved to pay for the first rather than to repeat it.

Trace event types

eml:run:starteml:assigneml:outputeml:run:done